在 C# 中, 当参数是引用类型并且是以传值的方式传入参数的时候 (没有加 ref 关键字), 方法传入的是这个对象的引用的一个副本, 相当于是以一个引用的值按照传值的方式调用方法, 这个引用在方法内部会生成一个副本, 就像普通的值类型变量一样, 但是由于这个引用的副本和原来方法外面的类型的引用是指向了同一个对象, 所以在方法内部对这个对象进行的各种操作 (改变对象的属性等) 看上去就像是按引用传递变量了一样, 返回之后对象会发生变化. 但是如果在方法内部对这个引用的副本进行了赋值操作, 那么这个引用的副本就不再指向原来的对象了, 方法返回后, 原来的对象自然也不会发生变化.
结论: 在 C# 的方法调用中, 传入引用类型做参数而没有加 ref 关键字的时候, 它仍然是以值传递的方式传递参数的, 只不过传入方法内部的是对象的引用的值.
具体下面的代码
- StringBuilder s1 = new StringBuilder();
- StringBuilder s2 = new StringBuilder();
- operatorstring(s1, s2);
- void operatorstring(StringBuilder sb1, StringBuilder sb2)
对 sb1 和 sb2 的操作会反应在 s1 和 s2 的值上面. 但是当 sb1 或者 sb2 的引用转向其地方, 则和 s1,s2 的值脱离干系了.
- static void Main(string[] args)
- {
- StringBuilder s1 = new StringBuilder("a");
- StringBuilder s2 = new StringBuilder("b");
- operatorstring(s1, s2);
- Console.WriteLine(s1.ToString() + "," + s2.ToString());
- }
- static void operatorstring(StringBuilder sb1, StringBuilder sb2)
- {
- sb1.Append("c");
- //sb2 = new StringBuilder();
- sb2.Append("c");
- }
此代码打印出 ac,bc
但当去掉注释, 变成
- static void operatorstring(StringBuilder sb1, StringBuilder sb2)
- {
- sb1.Append("c");
- sb2 = new StringBuilder();
- sb2.Append("c");
- }
则打印出 ac,b.
要真正的传递引用, 则要使用 ref 关键字
- [STAThread]
- static void Main(string[] args)
- {
- StringBuilder s1 = new StringBuilder("a");
- StringBuilder s2 = new StringBuilder("b");
- operatorstring(s1, ref s2);
- Console.WriteLine(s1.ToString() + "," + s2.ToString());
- }
- static void operatorstring(StringBuilder sb1, ref StringBuilder sb2)
- {
- sb1.Append("c");
- sb2 = new StringBuilder();
- sb2.Append("c");
- }
此代码打印出 ac,c
来源: http://www.bubuko.com/infodetail-3653734.html