.NET参数传递 - 通过参考V / S通过值 [英] .NET Parameter passing - by reference v/s by value

查看:118
本文介绍了.NET参数传递 - 通过参考V / S通过值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想验证我的理解C#/。NET / CLR对待值类型和引用类型。我已经看了这么多矛盾的解释,我STIL

这是我今天明白了,请纠正我,如果我的假设是错误的。

值类型,如int等住在栈上,引用类型住在托管堆中然而如果引用类型有例如有一个类型的实例变量双,这将生活连同其在堆对象

第二部分是我最困惑的。

让我们考虑一个简单的类叫做人。

人有一个名为Name属性。

可以说,我在另一个类中创建人物的一个实例,我们把它叫做UselessUtilityClass。

考虑以下code:

 类UselessUtilityClass
{
   无效AppendWithUnderScore(人P)
   {
     p.Name = p.Name +_;
   }
}
 

然后的地方,我们做的:

 者P =新的Person();
p.Name =牧师;
UselessUtilityClass U =新UselessUtilityClass();
u.AppendWithUnderScore(对);
 

人是引用类型,当传递给UselessUtilityClass - 这是我走到哪里 - 坚果......在变量 P,其是人参考的一个实例是由传递 VALUE ,这意味着当我写p.Name我会看到牧师_

然后,如果我写

 人员P2 = P;
 

和我做

p2.Name =不是牧师;

和写普的名称,比如下面我将获得不是牧师

  Console.WriteLine(p.Name)//将打印不是牧师
 

这是因为它们是引用类型和指向内存中的同一地址。

我的理解是否正确?

我觉得有一些误解怎么回事,当人们说的在.NET中的所有对象都通过引用过去了,这并不依据是什么,我认为JIVE。我可能是错的,这就是为什么我已经来到了堆垛机。

解决方案
  

值类型,如int等住在堆栈上。引用类型住在托管堆中然而如果引用类型有例如有一个类型的实例变量双,这将生活连同其上的堆对象

没有,这是不正确的。正确的说法是局部变量和值类型的形参既不是直接在迭代器块也不是封闭在一个lambda或匿名方法的外部变量被分配在执行的线程在微软实施的CLI的系统堆栈与微软实施的C#的。

不要求任何版本的C#或任何版本的CLI中使用该系统堆栈的任何东西。当然,我们这样做是因为它是一种方便的数据结构,局部变量和值类型的形式参数,这些参数不能直接在迭代器块或封闭在一个lambda或匿名方法的外部变量。

请参阅有关这一议题的讨论,我的文章(1)为什么这是是一个实现细节,以及(2)有什么好处,我们从这个实现选择得到的,和(3)有什么限制的欲望,使这个实现选择驶入语言设计。

<一个href="http://blogs.msdn.com/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx">http://blogs.msdn.com/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx

<一个href="http://blogs.msdn.com/ericlippert/archive/2009/05/04/the-stack-is-an-implementation-detail-part-two.aspx">http://blogs.msdn.com/ericlippert/archive/2009/05/04/the-stack-is-an-implementation-detail-part-two.aspx

  

人是引用类型,当传递给UselessUtilityClass - 这是我走到哪里 - 坚果...

深吸一口气。

一个变量是一个存储位置。每个存储位置具有相关联的类型。

一个存储位置,其相关的类型是引用类型可以包含的引用的该类型的对象,或者可以包含一个空引用。

一个存储位置,其相关的类型是值类型总是包含该类型的对象。

的变量是的存储单元的内容的。

  

变量p这是人参考的一个实例是按值传递,

变量p是一个存储位置。它包含对人的一个实例。因此,该变量的值是参考一个人。该值 - 引用一个实例 - 传递给被叫方。现在其他的变量,它已混淆性也被称为P,包含相同的值 - 该值是参考特定对象

现在,还可以通过一个引用的变量的,其中许多人感到迷惑。当你说一个更好的方式去思考它

 无效美孚(REF INT X){x = 10; }
...
INT P = 3456;
美孚(REF P);
 

这是什么意思是x是一个别名变量p。即,x和p为的两个名称的对的相同的变量的。这样的p任何值,这也是x的值,因为它们是两个名字相同的存储位置。

请意义了?

I'm trying to validate my understanding of how C#/.NET/CLR treats value types and reference types. I've read so many contradicting explanations I stil

This is what I understand today, please correct me if my assumptions are wrong.

Value types such as int etc live on the stack, Reference types live on the managed heap however if a reference type has for example has an instance variable of type double, it will live along with its object on the heap

The second part is what I am most confused about.

Lets consider a simple class called Person.

Person has a property called Name.

Lets say I create an instance of Person in another class, we'll call it UselessUtilityClass.

Consider the following code:

class UselessUtilityClass
{
   void AppendWithUnderScore(Person p)
   {
     p.Name = p.Name + "_";
   }
}

and then somewhere we do:

Person p = new Person();
p.Name = "Priest";
UselessUtilityClass u = new UselessUtilityClass();
u.AppendWithUnderScore(p);

Person is a reference type, when passed to UselessUtilityClass -- this is where I go - nuts...the VARIABLE p which is an instance of the Person reference is passed by VALUE, which means when I write p.Name I will see "Priest_"

And then if I wrote

Person p2 = p;

And I do

p2.Name = "Not a Priest";

And write p's name like below I will get "Not a Priest"

Console.WriteLine(p.Name) // will print "Not a Priest"

This is because they are reference types and point to the same address in memory.

Is my understanding correct?

I think there is some misunderstanding going on when people say All objects in .NET are passed by Reference, this doesn't jive based on what I think. I could be wrong, thats why I have come to the Stackers.

解决方案

Value types such as int etc live on the stack. Reference types live on the managed heap however if a reference type has for example has an instance variable of type double, it will live along with its object on the heap

No, this is not correct. A correct statement is "Local variables and formal parameters of value type which are neither directly in an iterator block nor closed-over outer variables of a lambda or anonymous method are allocated on the system stack of the executing thread in the Microsoft implementation of the CLI and the Microsoft implementation of C#."

There is no requirement that any version of C# or any version of the CLI use the system stack for anything. Of course we do so because it is a convenient data structure for local variables and formal parameters of value type which are not directly in an iterator block or closed-over outer variables of a lambda or anonymous method.

See my articles on this subject for a discussion of (1) why this is is an implementation detail, and (2) what benefits we get from this implementation choice, and (3) what restrictions the desire to make this implementation choice drives into the language design.

http://blogs.msdn.com/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx

http://blogs.msdn.com/ericlippert/archive/2009/05/04/the-stack-is-an-implementation-detail-part-two.aspx

Person is a reference type, when passed to UselessUtilityClass -- this is where I go - nuts...

Take a deep breath.

A variable is a storage location. Each storage location has an associated type.

A storage location whose associated type is a reference type may contain a reference to an object of that type, or may contain a null reference.

A storage location whose associated type is a value type always contains an object of that type.

The value of a variable is the contents of the storage location.

the VARIABLE p which is an instance of the Person reference is passed by VALUE,

The variable p is a storage location. It contains a reference to an instance of Person. Therefore, the value of the variable is a reference to a Person. That value -- a reference to an instance -- is passed to the callee. Now the other variable, which you have confusingly also called "p", contains the same value -- the value is a reference to a particular object.

Now, it is also possible to pass a reference to a variable, which many people find confusing. A better way to think about it is when you say

void Foo(ref int x) { x = 10; }
...
int p = 3456;
Foo(ref p);

what this means is "x is an alias for variable p". That is, x and p are two names for the same variable. So whatever the value of p is, that's also the value of x, because they are two names for the same storage location.

Make sense now?

这篇关于.NET参数传递 - 通过参考V / S通过值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆