值传递引用传递:在c#通过值和引用传递参数



在C#中既可以通过值也可以通过引用传递参数通过引用传递参数允许成员(思路方法、属性、索引器、运算符和构造)更改参数并保持该更改若要通过引用传递参数请使用ref或out关键字为简单起见本主题举例中只使用了ref关键字有关ref和out的间差异信息请参见、使用ref和out传递
本主题包括下列章节:
传递值类型参数
传递引用类型参数
它还包括以下举例:
举例演示是否使用ref或out
1通过值传递值类型否
2通过引用传递值类型是
3交换值类型(两个整数)是
4通过值传递引用类型否
5通过引用传递引用类型是
6交换引用类型(两个串)是
传递值类型参数
值类型变量直接包含其数据这和引用类型变量区别后者包含对其数据引用因此向思路方法传递值类型变量意味着向思路方法传递变量个副本思路方法内发生对参数更改对该变量中存储原始数据无任何影响如果希望所思路方法更改参数值必须使用ref或out关键字通过引用传递该参数为了简单起见以下举例使用ref
举例1:通过值传递值类型
下面举例演示通过值传递值类型参数通过值将变量myInt传递给思路方法SquareIt思路方法内发生任何更改对变量原始值无任何影响
//PassingParams1.csusing;PassingValByVal{voidSquareIt(x)//Theparameterxispassedbyvalue.//ChangestoxwillnotaffecttheoriginalvalueofmyInt.{x*=x;Console.WriteLine("Thevalueinsidethemethod:{0}",x);}publicvoidMain{myInt=5;Console.WriteLine("Thevaluebeforecallingthemethod:{0}",myInt);SquareIt(myInt);//PassingmyIntbyvalue.Console.WriteLine("Thevalueaftercallingthemethod:{0}",myInt);}}输出
Thevaluebeforecallingthemethod:5Thevalueinsidethemethod:25Thevalueaftercallingthemethod:5代码讨论
变量myInt为值类型包含其数据(值5)SquareIt时myInt内容被复制到参数x中在思路方法内将该参数求平方但在Main中myInt值在SquareIt思路方法的前和的后是相同实际上思路方法内发生更改只影响局部变量x
举例2:通过引用传递值类型
下面举例除使用ref关键字传递参数以外其余和“举例1”相同参数值在思路方法后发生更改
//PassingParams2.csusing;PassingValByRef{voidSquareIt(refx)//Theparameterxispassedbyreference.//ChangestoxwillaffecttheoriginalvalueofmyInt.{x*=x;Console.WriteLine("Thevalueinsidethemethod:{0}",x);}publicvoidMain{myInt=5;Console.WriteLine("Thevaluebeforecallingthemethod:{0}",myInt);SquareIt(refmyInt);//PassingmyIntbyreference.Console.WriteLine("Thevalueaftercallingthemethod:{0}",myInt);}}输出
Thevaluebeforecallingthemethod:5Thevalueinsidethemethod:25Thevalueaftercallingthemethod:25代码讨论
本举例中传递不是myInt而是对myInt引用参数x不是类型它是对引用(本例中为对myInt引用)因此当在思路方法内对x求平方时实际被求平方是x所引用项:myInt


举例3:交换值类型
更改所传递参数常见举例是Swap思路方法在该思路方法中传递x和y两个变量然后使思路方法交换它们内容必须通过引用向Swap思路方法传递参数;否则思路方法内所处理将是参数本地副本以下是使用引用参数Swap思路方法举例:
voidSwapByRef(refx,refy){temp=x;x=y;y=temp;}该思路方法时请在中使用ref关键字如下所示:
SwapByRef(refi,refj);传递引用类型参数
引用类型变量不直接包含其数据;它包含是对其数据引用当通过值传递引用类型参数时有可能更改引用所指向数据如某类成员但是无法更改引用本身值;也就是说不能使用相同引用为新类分配内存并使的在块外保持若要这样做请使用ref(或out)关键字传递参数为了简单起见以下举例使用ref
举例4:通过值传递引用类型
下面举例演示通过值向Change思路方法传递引用类型参数myArray由于该参数是对myArray引用所以有可能更改元素但是试图将参数重新分配到区别内存位置时该操作仅在思路方法内有效并不影响原始变量myArray
//PassingParams4.cs//Passingan.gif' />toamethodwithouttherefkeyword.//ComparetheresultstothoseofExample5.using;PassingRefByVal{voidChange(arr){arr[0]=888;//Thischangeaffectstheoriginalelement.arr=[5]{-3,-1,-2,-3,-4};//Thischangeislocal.Console.WriteLine("Insidethemethod,thefirstelementis:{0}",arr[0]);}publicvoidMain{myArray={1,4,5};Console.WriteLine("InsideMain,beforecallingthemethod,thefirstelementis:{0}",myArray[0]);Change(myArray);Console.WriteLine("InsideMain,aftercallingthemethod,thefirstelementis:{0}",myArray[0]);}}输出
InsideMain,beforecallingthemethod,thefirstelementis:1Insidethemethod,thefirstelementis:-3InsideMain,aftercallingthemethod,thefirstelementis:888代码讨论
在上个举例中myArray为引用类型在未使用ref参数情况下传递给思路方法在此情况下将向思路方法传递指向myArray引用个副本输出显示思路方法有可能更改元素内容(从1改为888)但是在Change思路方法内使用运算符分配新内存部分将使变量arr引用新因此这的后任何更改都不会影响原始myArray(它是在Main内创建)实际上本举例中创建了两个个在Main内个在Change思路方法内
举例5:通过引用传递引用类型
本举例除在思路方法头和中使用ref关键字以外其余和“举例4”相同思路方法内发生任何更改都会影响原始变量
//PassingParams5.cs//Passingan.gif' />toamethodwiththerefkeyword.//ComparetheresultstothoseofExample4.using;PassingRefByRef{voidChange(refarr){//Bothofthefollowingchangeswillaffecttheoriginalvariables:arr[0]=888;arr=[5]{-3,-1,-2,-3,-4};Console.WriteLine("Insidethemethod,thefirstelementis:{0}",arr[0]);}publicvoidMain{myArray={1,4,5};Console.WriteLine("InsideMain,beforecallingthemethod,thefirstelementis:{0}",myArray[0]);Change(refmyArray);Console.WriteLine("InsideMain,aftercallingthemethod,thefirstelementis:{0}",myArray[0]);}}输出


InsideMain,beforecallingthemethod,thefirstelementis:1Insidethemethod,thefirstelementis:-3InsideMain,aftercallingthemethod,thefirstelementis:-3代码讨论
思路方法内发生所有更改都影响Main中原始实际上使用运算符对原始进行了重新分配因此Change思路方法后对myArray任何引用都将指向Change思路方法中创建 5个元素
举例6:交换两个
交换串是通过引用传递引用类型参数很好举例本举例中str1和str2两个串在Main中并作为由ref关键字修饰参数传递给SwapStrings思路方法这两个串在该思路方法内以及Main内均进行交换
//PassingParams6.csusing;SwappinStrings{voidSwapStrings(refs1,refs2)//Theparameterxispassedbyreference.//Anychangesonparameterswillaffecttheoriginalvariables.{temp=s1;s1=s2;s2=temp;Console.WriteLine("Insidethemethod:{0},{1}",s1,s2);}publicvoidMain{str1="John";str2="Smith";Console.WriteLine("InsideMain,beforeswapping:{0}{1}",str1,str2);SwapStrings(refstr1,refstr2);//PassingsbyreferenceConsole.WriteLine("InsideMain,afterswapping:{0},{1}",str1,str2);}}输出
InsideMain,beforeswapping:JohnSmithInsidethemethod:Smith,JohnInsideMain,afterswapping:Smith,John代码讨论
本举例中需要通过引用传递参数以影响变量如果同时从思路方法头和思路方法中移除ref关键字中不会发生任何更改
Tags:  参数传递方式 jsp参数传递 参数传递 值传递引用传递

延伸阅读

最新评论

发表评论