理解C#中參數(shù)的值和引用以及傳遞結(jié)構(gòu)和類引用的區(qū)別
值與引用參數(shù)之間的區(qū)別:
在 C# 中,既可以通過值也可以通過引用傳遞參數(shù)。在調(diào)用環(huán)境中通過引用傳遞參數(shù)允許函數(shù)成員(方法、屬性、索引器、運(yùn)算符和構(gòu)造函數(shù))更改參數(shù)的值,并保持該更改。若要通過引用傳遞參數(shù),請使用 ref 或 out 關(guān)鍵字。
下面的示例闡釋值與引用參數(shù)之間的區(qū)別:
class Program
{
static void Main(string[] args)
{
int arg;
// Passing by value.
// The value of arg in Main is not changed.
arg = 4;
squareVal(arg);
Console.WriteLine(arg);
// Output: 4
// Passing by reference.
// The value of arg in Main is changed.
arg = 4;
squareRef(ref arg);
Console.WriteLine(arg);
// Output: 16
}
static void squareVal(int valParameter)
{
valParameter *= valParameter;
}
// Passing by reference
static void squareRef(ref int refParameter)
{
refParameter *= refParameter;
}
}
向方法傳遞結(jié)構(gòu)和向方法傳遞類引用之間的區(qū)別
下面的示例演示如何使用 結(jié)構(gòu) 到方法與通過 類 實例不同傳遞給方法。在此示例中,兩個參數(shù) (結(jié)構(gòu)和類實例) 將值和兩個方法通過更改參數(shù)的一個字段的值。但是,這兩個方法的結(jié)果是不同的,因為的傳遞,當(dāng)您通過時結(jié)構(gòu)什么不同通過,則可以通過類的實例。
由于結(jié)構(gòu)是 值類型,那么,當(dāng)您對方法的 使用結(jié)構(gòu)值 ,方法受到并對結(jié)構(gòu)參數(shù)的副本。方法無法訪問原始結(jié)構(gòu)中調(diào)用方法并不能將其更改任何方式。該方法可以僅更改副本。
類的實例是 引用類型,而不是值類型。當(dāng)對方法的 引用類型通過值 ,方法進(jìn)行引用的復(fù)制到類實例。即方法受到實例,而不是復(fù)制實例的地址的副本。在調(diào)用方法的類實例都有一個地址,在調(diào)用方法的參數(shù)的地址的副本,因此,兩個地址是否引用同一對象。由于該參數(shù)包含該地址的副本,調(diào)用方法不能更改類實例的地址在調(diào)用方法的。但是,調(diào)用方法可以使用該地址訪問原始地址和該副本引用的類成員。如果調(diào)用方法將類成員,在調(diào)用方法的原始類的實例也會發(fā)生更改。
下面的示例的輸出顯示差異。,因為該方法在參數(shù)中使用該地址查找類的實例,的指定字段調(diào)用將類實例的 willIChange 字段的值傳遞給方法 ClassTaker 。調(diào)用不更改結(jié)構(gòu)的 willIChange 字段在調(diào)用方法為方法 StructTaker ,因為參數(shù)的值是結(jié)構(gòu)的副本,而不是復(fù)制其地址。 StructTaker 更改該副本,因此,該副本丟失,在向 StructTaker 調(diào)用完成時。
class TheClass
{
public string willIChange;
}
struct TheStruct
{
public string willIChange;
}
class TestClassAndStruct
{
static void ClassTaker(TheClass c)
{
c.willIChange = "Changed";
}
static void StructTaker(TheStruct s)
{
s.willIChange = "Changed";
}
static void Main()
{
TheClass testClass = new TheClass();
TheStruct testStruct = new TheStruct();
testClass.willIChange = "Not Changed";
testStruct.willIChange = "Not Changed";
ClassTaker(testClass);
StructTaker(testStruct);
Console.WriteLine("Class field = {0}", testClass.willIChange);
Console.WriteLine("Struct field = {0}", testStruct.willIChange);
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
輸出:
Class field = Changed Struct field = Not Changed
相關(guān)文章
VSCode配置C#運(yùn)行環(huán)境的完整步驟
這篇文章主要給大家介紹了關(guān)于VSCode配置C#運(yùn)行環(huán)境的完整步驟,文中通過圖文介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09

