C#使用引用参数

C# using reference parameters

本问题已经有最佳答案,请猛点这里访问。

引用参数仅对值类型有用?例如,如果有一个方法在类中传递,那么ref关键字是无用的?

1
2
3
4
5
6
7
8
9
public class someclass
{

}    

somefunction(ref someclass input)
{

}


您当然可以为类类型使用ref参数。例如:

1
2
3
4
5
6
7
8
void MyClassFactory(ref MyClass newRef)
{
    newRef = new MyClass();
}

MyClass someRef = null;
MyClassFactory(ref someRef);
// Now someRef is referencing a new MyClass object.

注意,如果没有ref关键字,上述代码将无法工作。


我的理解是(如果我错了,我希望有人纠正我):

C包含值类型(在堆栈上分配)和引用类型(在堆上分配)。

但是,默认情况下,所有参数都是按值传递的,这意味着如果调用函数

1
2
3
4
5
myFunc(myClass param) { }
...
myClass myVar = new myClass();
myFunc(myVar);
//myVar will not be changed here

然后会创建一个廉价的myvar副本并传递到myfunc。

如果使用"ref"关键字传递相同的参数,则不会生成myvar的副本,而是传入对myvar的引用。一旦myfunc返回,myvar中对myvar所做的任何更改都将反映在myvar中。

1
2
3
4
5
myFunc(ref myClass param) { }
...
myClass myVar = new myClass();
myFunc(ref myVar);
//myVar might be changed here

我很难找到一篇真正讨论参数的文章,不仅仅是关于值与引用类型的文章,我认为这就是它的工作原理。


如果需要用新对象替换给定函数的对象,则ref对于引用类型很有用。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class MyClass
{

}

class MyClass2 : MyClass
{
   public MyClass2(MyClass original)
   {
   }
}

bool UpdateMyClass(ref MyClass input)
{
   bool success = false;

   if (input != null)
   {
       //Generate a new object with some additional functionality.
       input = new MyClassWithSuperPowers(input);
       success = true;
   }

   return success;
}

当然,最明显的用例是字符串类。

1
2
3
4
void FormatString(ref string data)
{
  data = DateTime.Now + data;
}