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



在 C# 中既可以通过值也可以通过引用传递参数通过引用传递参数允许成员(思路方法、属性、索引器、运算符和构造)更改参数并保持该更改若要通过引用传递参数请使用 ref 或 out 关键字为简单起见本主题举例中只使用了 =STYLE1>ref 关键字有关 ref 和 out 的间差异信息请参见、使用 ref 和 out 传递

本主题包括下列章节:

  • 传递值类型参数
  • 传递引用类型参数
它还包括以下举例:

举例 演示 是否使用 ref 或 out
1 通过值传递值类型 否
2 通过引用传递值类型 是
3 交换值类型(两个整数) 是
4 通过值传递引用类型 否
5 通过引用传递引用类型 是
6 交换引用类型(两个串) 是


=dtH2>传递值类型参数

=STYLE1>值类型变量直接包含其数据这和=STYLE1>引用类型变量区别后者包含对其数据引用因此向思路方法传递值类型变量意味着向思路方法传递变量个副本思路方法内发生对参数更改对该变量中存储原始数据无任何影响如果希望所思路方法更改参数值必须使用 ref 或 out 关键字通过引用传递该参数为了简单起见以下举例使用 ref

=dtH4>举例 1:通过值传递值类型

下面举例演示通过值传递值类型参数通过值将变量 myInt 传递给思路方法 SquareIt思路方法内发生任何更改对变量原始值无任何影响

//PassingParams1.cs
using;
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);
}

}





=dtH4>输出

The value before calling the method: 5
The value inside the method: 25
The value after calling the method: 5

=dtH4>代码讨论

变量 myInt 为值类型包含其数据(值 5) SquareIt 时myInt 内容被复制到参数 x 中在思路方法内将该参数求平方但在 Main 中myInt 值在 SquareIt 思路方法的前和的后是相同实际上思路方法内发生更改只影响局部变量 x

=dtH4>举例 2:通过引用传递值类型

下面举例除使用 ref 关键字传递参数以外其余和“举例 1”相同参数值在思路方法后发生更改

//PassingParams2.cs
using;
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);
}

}





=dtH4>输出

The value before calling the method: 5
The value inside the method: 25
The value after calling the method: 25

=dtH4>代码讨论

本举例中传递不是 myInt 而是对 myInt 引用参数 x 不是 类型它是对 引用(本例中为对 myInt 引用)因此当在思路方法内对 x 求平方时实际被求平方是 x 所引用项:myInt

=dtH4>举例 3:交换值类型

更改所传递参数常见举例是 Swap 思路方法在该思路方法中传递 x 和 y 两个变量然后使思路方法交换它们内容必须通过引用向 Swap 思路方法传递参数;否则思路方法内所处理将是参数本地副本以下是使用引用参数 Swap 思路方法举例:

voidSwapByRef(refx,refy)
{
temp=x;
x
=y;
y
=temp;
}





该思路方法时请在中使用 ref 关键字如下所示:

SwapByRef (ref i, ref j);









传递引用类型参数

=STYLE1>引用类型变量不直接包含其数据;它包含是对其数据引用当通过值传递引用类型参数时有可能更改引用所指向数据如某类成员但是无法更改引用本身值;也就是说不能使用相同引用为新类分配内存并使的在块外保持若要这样做请使用 ref(或 out)关键字传递参数为了简单起见以下举例使用 ref

=dtH4>举例 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]);
}

}





=dtH4>输出

Inside Main, before calling the method, the first element is: 1
Inside the method, the first element is: -3
Inside Main, after calling the method, the first element is: 888

=dtH4>代码讨论

在上个举例中 myArray 为引用类型在未使用 ref 参数情况下传递给思路方法在此情况下将向思路方法传递指向 myArray 引用个副本输出显示思路方法有可能更改元素内容(从 1 改为 888)但是在 Change 思路方法内使用 运算符分配新内存部分将使变量 arr 引用新因此这的后任何更改都不会影响原始 myArray(它是在 Main 内创建)实际上本举例中创建了两个个在 Main 内个在 Change 思路方法内

=dtH4>举例 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]);
}

}





=dtH4>输出

Inside Main, before calling the method, the first element is: 1
Inside the method, the first element is: -3
Inside Main, after calling the method, the first element is: -3

=dtH4>代码讨论

思路方法内发生所有更改都影响 Main 中原始实际上使用 运算符对原始进行了重新分配因此 Change 思路方法后对 myArray 任何引用都将指向 Change 思路方法中创建 5个元素

=dtH4>举例 6:交换两个

交换串是通过引用传递引用类型参数很好举例本举例中str1 和 str2 两个串在 Main 中并作为由 ref 关键字修饰参数传递给 SwapStrings 思路方法这两个串在该思路方法内以及 Main 内均进行交换

//PassingParams6.cs
using;
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);//Passingsbyreference
Console.WriteLine("InsideMain,afterswapping:{0},{1}",
str1,str2);
}

}





=dtH4>输出

Inside Main, before swapping: John Smith
Inside the method: Smith, John
Inside Main, after swapping: Smith, John

=dtH4>代码讨论

本举例中需要通过引用传递参数以影响变量如果同时从思路方法头和思路方法中移除 ref 关键字中不会发生任何更改



Tags:  参数传递方式 jsp参数传递 参数传递 值传递引用传递

延伸阅读

最新评论

发表评论