这对我来说非常时髦,显然开发人员应该使用关键字out但我不相信这甚至可以工作:
public BusinessResponse<MyResultType> MyMethod(){
BusinessResponse<MyResultType> res = new BusinessResponse<MyResultType>();
ProcessResult(res);
return res; //this has the values set by ProcessResult!!! How?
}
private void ProcessResult(BusinessResponse<MyResultType> result)
{
result.State = BusinessResponseState.Success;
//set some other stuff in the result argument
}
Run Code Online (Sandbox Code Playgroud)
我的同事说这被称为"深度参考",我不敢相信这在C#中起作用.我会重构使用outaka private void ProcessResult(out BusinessResponse<MyResultType> result)但我仍然想知道为什么这段代码有效.
UPDATE
所以看起来我不正确,这段代码很好.似乎情绪是,作为C#开发人员,我应该立即知道,因为传递给processResult的参数是堆上的引用类型,通过值传入引用本身的副本,并且复制的引用仍然指向同一个对象.
Jon*_*art 11
当然在你的情况下BusinessResponse<T>是一个class,也称为"参考类型".引用类型(对象)总是在C#中"通过引用"传递(类似于好的C中的指针)1.
这意味着无论你如何传递引用,它仍然指的是内存中的一个实例.这意味着无论你如何引用它,你总是修改同一个副本.
1 - 这不完全正确.实际发生的是引用(变量)按值传递.当函数接收到此引用时(再次,想到托管堆上某个对象的指针),它将引用同一个对象.但是,引用本身在传入时被复制.
我们使用的另一种变量是"值类型".这是structS,以及所有像元的char,bool,int等,这些都是意料之中总是传递由值,这意味着一份拷贝每次分配一个值类型的新变量(包括它传递给函数)时间.要通过函数调用修改这些,您必须使用ref或out关键字.
那么什么时候使用ref引用类型?
当您想要更改变量引用的实例时:
public class Foo {
public string Name { get; private set; }
public Foo(string name) {
Name = name;
}
}
public class Program {
public static void Example(ref Foo f) {
// This will print "original"
Console.WriteLine("Example() was given {0}", f.Name);
// We assign a new instance to the reference which was
// passed by reference
f = new Foo("replacement");
}
public static void Main() {
Foo f; // This variable is a "reference" to a Foo
f = new Foo("original"); // We assign a new instance to that variable
Example(ref f);
// This will print "replacement"
Console.WriteLine("After calling Example(), f is {0}", f.Name);
}
}
Run Code Online (Sandbox Code Playgroud)