对我来说这很时髦,显然开发人员应该使用关键字输出,但我无法相信这甚至有效:
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
}
我的同事说这被称为“深度参考”,我无法相信这在C#中有效。我会重构使用out
aka private void ProcessResult(out BusinessResponse<MyResultType> result)
,但我仍然想知道为什么这段代码有用。
更新
所以看起来我不正确,这段代码很好。似乎情绪是,作为C#开发人员,我应该立即知道,因为传递给processResult的参数是堆上的引用类型,通过值传入引用本身的副本,并且复制的引用仍然指向相同的对象。
答案 0 :(得分:10)
当然,在您的情况下,BusinessResponse<T>
是class
,也称为"reference type"。引用类型(对象)始终在C#中“通过引用”传递(类似于好的C中的指针) 1 。
这意味着无论你如何传递引用,它仍然指的是内存中的一个实例。这意味着无论你如何引用,你总是修改同一个副本。
1 - 这不完全正确。实际发生的是引用(变量)按值传递。当函数接收到此引用时(再次,想到托管堆上某个对象的指针),它将引用同一个对象。但是,引用本身在传入时被复制。
我们使用的另一种变量是“值类型”。这些是struct
,以及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);
}
}
答案 1 :(得分:0)
这需要一点点挖掘;您正在发现值类型和引用类型的差异。当这么多已经在线时,我不会给你我的两分钱。这里有几篇文章
basic difference between value types and reference types
Reference and Value types scenario
What is a Value Class and what is a reference Class in C#?
最后一点,MSDN文章为http://msdn.microsoft.com/en-us/library/4d43ts61%28v=vs.90%29.aspx