學過C/C++的人,對C#的關鍵字Ref和Out應該都很好理解。它們都提供了一種可以在被調(diào)用函數(shù)內(nèi)修改傳遞的參數(shù)的值的方法。因為這一功能很類似C/C++的指針。對于沒學過C/C++的,也應該可以明白這兩個參數(shù)的作用。
雖然Ref和Out都提供了修改參數(shù)值的方法,但它們還是有一點點小的區(qū)別。
1、Ref在作為參數(shù)調(diào)用函數(shù)之前,變量一定要賦值,否則會得到一個常規(guī)編譯錯誤:使用了未賦值的變量。
2、在被調(diào)用函數(shù)內(nèi),以Ref引入的參數(shù)在返回前不必為它賦值。
3、Out在作為參數(shù)調(diào)用函數(shù)之前,變量可以不被賦值。
4、在被調(diào)用函數(shù)內(nèi),以Out引入的參數(shù)在返回前一定要至少賦值一次。
其實本質(zhì)上講,Ref更適合理解為給被調(diào)用函數(shù)傳遞了一個與原參考同地址的變量。而Out則可以理解為在調(diào)用函數(shù)前,先給變量找個地方,讓被調(diào)用函數(shù)在給定地點放一個值。
看上去很簡單不是嗎?確實如此,這里是一個例子:
namespace StudyAndTest


{

/**////
/// Summary description for Class1.
///
class Class1

{

/**////
/// The main entry point for the application.
///
[STAThread]
static void Main(string[] args)

{
int m_temp =0; //Must be assigned to before call any mothed with the
variable by reference.
Console.WriteLine("Int data befor change:{0}",m_temp);
ChangeData1(ref m_temp);
Console.WriteLine("Int data after change:{0}",m_temp);
ChangeData2(out m_temp);
Console.WriteLine("Int data after change:{0}",m_temp);
}

static void ChangeData1(ref int i_ref)

{
Console.WriteLine("Int data in ChangeData1:{0}",i_ref);
i_ref = 1;
}

static void ChangeData2(out int i_ref)

{
//Console.WriteLine("Int data in ChangeData2:{0}",i_ref); //Error in building, use of unassigned local variable i_ref
i_ref = 2; //The out parament i_ref must be assigned to before control leaves the
current mothod.
}
}
}但如果我們強行加上Ref或者Out關鍵字,會是什么結(jié)果呢???
1、如果是用Ref,那么結(jié)果是和什么都沒用一樣!即默認就是用的Ref。(讓我們少打了幾個字符)
2、如果是用Out,那么要遵守上面的3,4原則,即:在調(diào)用前,不必初始化引用對象,再簡單一點:就是可以不用New一個對象。但在函數(shù)內(nèi),返回前一定要New一個,并且在New之前,參數(shù)對象是不能使用的。
也就是上面說到的,Out只是在調(diào)用前分配了一個地點,在調(diào)用函數(shù)中使用該地點。注意:這里“地點”一詞決不是內(nèi)存地址。
再思考一個問題:如果在使用Out參考時,在調(diào)用函數(shù)前,我們已經(jīng)New了一個對象,再來調(diào)用函數(shù)結(jié)果會是什么呢?
你將“丟失”一部份內(nèi)存(如果在C/C++里,一定是這樣的)。也就是說,在調(diào)用了函數(shù)后,函數(shù)里New的一個對象會讓函數(shù)外的對象丟失,而新的對象在函數(shù)內(nèi)有效,在函數(shù)外也有效。幸運的是:原來的對象的內(nèi)存并不會像C/C++那樣完全的丟失,它將由垃圾回收器來管理了。所以我們并不擔心內(nèi)存的真正丟失問題(這真是一件值得慶幸的事)。
看這樣的例子:
class Class1

{

/**////
/// The main entry point for the application.
///
[STAThread]
static void Main(string[] args)

{
TempClass m_class1 = new TempClass();
m_class1.m_member = 0;
Console.WriteLine("i_obj data before changeData3 :{0}",m_class1.m_member);
ChangeData3(out m_class1);
Console.WriteLine("i_obj data after changeData3 :{0}",m_class1.m_member);

}
static void ChangeData3(out TempClass i_obj)

{
i_obj = new TempClass();
i_obj.m_member = 3;
// Console.WriteLine("i_obj data in ChangeData3:{0}",i_obj.m_member);
}
}

class TempClass

{
public int m_member;
}
NET技術:深入剖析引用參數(shù)Ref和Out,轉(zhuǎn)載需保留來源!
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。