首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >引用类型,由引用传递,不引用引用

引用类型,由引用传递,不引用引用
EN

Stack Overflow用户
提问于 2018-11-19 06:15:51
回答 3查看 114关注 0票数 2

在以不同的方式调用4种方法时,我得到了不同的结果:

代码语言:javascript
复制
static void Main(string[] args)
{
   var emp = new Employee { Name = "ABC" };

   ChangeName1(emp);
   Console.WriteLine(emp.Name); //XYZ

   ChangeName2(ref emp);
   Console.WriteLine(emp.Name); //XYZ

   ChangeToNull1(emp);
   Console.WriteLine(emp.Name); // XYZ

   ChangeToNull2(ref emp);
   Console.WriteLine(emp.Name); // Null Reference Exception

   Console.ReadLine();
}

static void ChangeName1(Employee e)
{
   e.Name = "XYZ";
}
static void ChangeName2(ref Employee e)
{
   e.Name = "XYZ";
}
static void ChangeToNull1(Employee e)
{
   e = null;
}
static void ChangeToNull2(ref Employee e)
{
   e = null;
}

正如您可以看到的前两个方法一样,我正在更改Name属性的值,并且在从该方法返回后,原始对象属性将被更改。

但是,当将对象设置为null时,ChangeToNull1方法不会更改原始对象,但是ChangeToNull2方法会更改。

所以我的问题是:

1.为什么C#这样做?

2.在传递给方法时,C#会复制原始对象吗?

3.如果它改变了原始对象属性(如Name ),为什么不更改原始对象呢?

4.在由ref传递时c#是否复制原始对象?

EN

回答 3

Stack Overflow用户

发布于 2018-11-19 06:29:18

它的行为是这样的,因为C#传递指向引用类型的指针值的副本。这是一口口香糖,所以这可能会更有启发性:

当你写:

代码语言:javascript
复制
var emp = new Employee { Name = "ABC" }; 

您正在创建一个Employee实例,并将指向该对象的指针存储在变量emp中。让我们假设emp的内存位置是0x000001。该值(对象的位置)为0x0000AA

当你打电话:

代码语言:javascript
复制
ChangeName1(emp);

您正在传递值0x0000AA。在方法ChangeName1中,e的值是0x0000AA,但它的位置不是0x000001。它存储在记忆中的另一个地方。

然而,当你打电话:

代码语言:javascript
复制
ChangeName2(ref emp);

您正在传递emp的内存位置,即0x000001。因此,在此方法中,更新e还会更新emp

要解决成员问题--正如上面所指出的,您没有复制对象。ChangeName1ChangeName2都引用同一个对象。它们都是指存储在0x0000AA上的对象。

有关进一步阅读,请参见When is a C# value/object copied and when is its reference copied?

票数 2
EN

Stack Overflow用户

发布于 2018-11-19 06:31:07

代码语言:javascript
复制
static void ChangeName1(Employee e)
{
   e.Name = "XYZ";
}

在这里,新指针"e“指向同一个对象"emp”-因此更改反映。

代码语言:javascript
复制
static void ChangeName2(ref Employee e)
{
   e.Name = "XYZ";
}

这里"emp“作为引用传递-只是它的名称e。(很容易理解这种方式)。

代码语言:javascript
复制
static void ChangeToNull1(Employee e)
{
   e = null;
}

在这里,新指针"e“指向相同的对象"emp”--当您设置e=空时。新指针为null,而不是原始对象。

代码语言:javascript
复制
static void ChangeToNull2(ref Employee e)
{
   e = null;
}

我想你现在已经明白发生了什么。

票数 1
EN

Stack Overflow用户

发布于 2018-11-19 06:34:08

"emp“是一个引用变量。指向引用类型实例的变量。

引用变量的工作方式类似于指针的工作方式。裸指针是编程的一个非常基本的工具,但是处理它们是可怕的危险。因此,.NET团队选择不强制您默认处理它们。但是,由于它们是如此重要,许多东西必须被发明出来才能修复它们(参考文献和代表是jsut 2常见的)。

内存中的对象和您持有的引用的(数量)是完全不确定的。内存中的对象可以有0、1或多个引用指向它。当GC选择下一个运行时,没有任何引用的对象将被GC收集。

将引用设置为null并不会强制集合,它会使集合成为可能。A具有很高的可能性,给出更多的运行时。但从来都不是保证。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53369231

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档