理解C#中参数的值和引用以及传递结构和类引用的区别
值与引用参数之间的区别:
在C#中,既可以通过值也可以通过引用传递参数。在调用环境中通过引用传递参数允许函数成员(方法、属性、索引器、运算符和构造函数)更改参数的值,并保持该更改。若要通过引用传递参数,请使用ref或out关键字。
下面的示例阐释值与引用参数之间的区别:
classProgram { staticvoidMain(string[]args) { intarg; //Passingbyvalue. //ThevalueofarginMainisnotchanged. arg=4; squareVal(arg); Console.WriteLine(arg); //Output:4 //Passingbyreference. //ThevalueofarginMainischanged. arg=4; squareRef(refarg); Console.WriteLine(arg); //Output:16 } staticvoidsquareVal(intvalParameter) { valParameter*=valParameter; } //Passingbyreference staticvoidsquareRef(refintrefParameter) { refParameter*=refParameter; } }
向方法传递结构和向方法传递类引用之间的区别
下面的示例演示如何使用结构到方法与通过类实例不同传递给方法。在此示例中,两个参数(结构和类实例)将值和两个方法通过更改参数的一个字段的值。但是,这两个方法的结果是不同的,因为的传递,当您通过时结构什么不同通过,则可以通过类的实例。
由于结构是值类型,那么,当您对方法的使用结构值,方法受到并对结构参数的副本。方法无法访问原始结构中调用方法并不能将其更改任何方式。该方法可以仅更改副本。
类的实例是引用类型,而不是值类型。当对方法的引用类型通过值,方法进行引用的复制到类实例。即方法受到实例,而不是复制实例的地址的副本。在调用方法的类实例都有一个地址,在调用方法的参数的地址的副本,因此,两个地址是否引用同一对象。由于该参数包含该地址的副本,调用方法不能更改类实例的地址在调用方法的。但是,调用方法可以使用该地址访问原始地址和该副本引用的类成员。如果调用方法将类成员,在调用方法的原始类的实例也会发生更改。
下面的示例的输出显示差异。,因为该方法在参数中使用该地址查找类的实例,的指定字段调用将类实例的willIChange字段的值传递给方法ClassTaker。调用不更改结构的willIChange字段在调用方法为方法StructTaker,因为参数的值是结构的副本,而不是复制其地址。StructTaker更改该副本,因此,该副本丢失,在向StructTaker调用完成时。
classTheClass { publicstringwillIChange; } structTheStruct { publicstringwillIChange; } classTestClassAndStruct { staticvoidClassTaker(TheClassc) { c.willIChange="Changed"; } staticvoidStructTaker(TheStructs) { s.willIChange="Changed"; } staticvoidMain() { TheClasstestClass=newTheClass(); TheStructtestStruct=newTheStruct(); testClass.willIChange="NotChanged"; testStruct.willIChange="NotChanged"; ClassTaker(testClass); StructTaker(testStruct); Console.WriteLine("Classfield={0}",testClass.willIChange); Console.WriteLine("Structfield={0}",testStruct.willIChange); //Keeptheconsolewindowopenindebugmode. Console.WriteLine("Pressanykeytoexit."); Console.ReadKey(); } }
输出:
Classfield=Changed Structfield=NotChanged