2009-01-12 46 views
4

更新所以完全拉了一个工具时刻。我的意思是通过参考与出/参考。凡是说 '裁判' 我真的被引用意味着在C#Out参数问题:Out如何处理值类型?

的someMethod(对象someObject)

对战

的someMethod(出someObject)

对不起。只是不想更改代码,所以答案已经有意义。

据我所知,不像裁判那里“复制”指针并创建堆栈上的新空间,使用指针,但不会改变指针:

SomeMethod() 
{ 
SomeThing outer = new SomeThing(); 
RefMethod(ref outer) 
} 

RefMethod(ref inner) //new space on stack created and uses same pointer as outer 
{ 
    inner.Hi = "There"; //updated the object being pointed to by outer 
    inner = new SomeThing();//Given a new pointer, no longer shares pointer with outer 
          //New object on the heap 
} 

出副本指针,可以操纵它指向的:

SomeMethod() 
{ 
SomeThing outer = new SomeThing(); 
RefMethod(out outer) 
} 

RefMethod(out inner) //same pointer shared 
{ 

    inner = new SomeThing();//pointer now points to new place on heap 
          //outer now points to new object 
          //Old object is orphaned if nothing else points to it 
} 

这很好,很正常,使用对象,但对于值类型看到,因为他们没有什么指向仅为堆栈?

回答

9

仅仅因为变量存在于栈上(如果它是一个局部变量)并不意味着你不能创建一个指向它的指针 - 事实上,引用类型也是如此。

RefMethod中的指针指向“外部”变量 - 并且变量本身位于堆栈上,因为它是未捕获的局部变量。

正如Leppie所说,除了关于明确赋值的规则外,ref和out是相同的 - 事实上,IL中唯一的区别是应用于输出参数的属性。

查看my article on parameter passing了解更多有关ref/out的细节。

3

就我所知,ref和out是完全一样的,只是out参数不能被初始化。因此两者都在堆叠中。

+0

我认为你的意思是一个out参数*有*必须在方法内的正常返回之前明确赋值;一个用作out参数的变量不必在调用之前明确赋值,尽管它可以是。 (这将在之后。) – 2009-01-12 19:53:35

+0

要添加到Jon所说的,ref参数必须被初始化,并且out参数不必是(但可以)。 – 2009-01-12 19:56:49

1

实际上使用ref或out引用类型也会创建一个指针...不是指向对象,而是指向对象的引用! 因此,这将是某种

RefMethod(SomeThing **inner) 
{ 
} 
在C++

,而值类型这将是

RefMethod2(int *inner) 
{ 
} 

值类型。