2012-02-16 76 views
1

比方说,我有对象的列表和我解压,然后从列表这样的修改项目:C#通过引用或值

List<MyObject> TheListOfObjects = new List<MyObject>(); 
MyObject TheObject = new MyObject(); 

TheListOfObjects = //some json deserialization result 

TheObject = (from o in TheListOfObject 
      where o.ID == SomeParameter 
      select o).SingleOrDefault(); 

TheObject.SomeProperty = SomeValue; 

当我写TheObject.SomeProperty = SomeValue;我是:

  1. 修改列表中的项目,在这种情况下,我完成或
  2. 修改一个新的项目,我必须用我刚刚修改的项目替换列表中的原始项目。
+5

您已经编写了代码;尝试一下,看看会发生什么! – 2012-02-16 15:05:39

+1

我不明白你为什么要创建* new *对象,然后通过将新实例分配给变量来抛出它们? – 2012-02-16 15:14:36

+0

@EricLippert:有时候事情是偶然发生,然后停止工作,我只是想澄清一下,我得到的真的是我想要的。你在书中读到byval vs byref,但实际上你确实在学习。 – frenchie 2012-02-16 15:33:59

回答

6

取决于。

如果对象列表是一个类实例列表,则TheObject变量将保存一个值参考。该参考也将在列表中存在。在该参考中的对象的修改将在两者中都可见。重要提示:在变量中包含的引用(即变量重新分配)上的写作不会保留到列表中,也不会在列表中的引用上继续写入变量。

如果对象列表是结构实例列表,则TheObject只包含,并且该值的突变在列表内不可见。

+0

为什么有人会在类上使用结构? – frenchie 2012-02-16 15:08:47

+1

因为有时结构语义(byval copy和成员比较)正是你所需要的。 – GSerg 2012-02-16 15:09:20

+0

@frenchie,看到[这个相关的问题](http://stackoverflow.com/questions/85553/when-should-i-use-a-struct-instead-of-a-class) – 2012-02-16 15:11:04

1

您正在修改列表中的项目,因为调用返回对列表中项目的引用,而不是其副本。而且,对象你

MyObject TheObject = new MyObject(); 

创建只是扔掉,因为你改变了参照新选择的项目。你可以省略这行,只是做:

MyObject theObject = (from o in TheListOfObject 
     where o.ID == SomeParameter 
     select o).SingleOrDefault(); 

我假设的MyObject是一个类,而不是一个结构,因为我们正在与操作变异它,mutable structs are evil

1

在项目的列表是通过引用保存的,所以你修改同一个对象 - 不需要尝试将它复制回列表中,因为它已经在那里。

1

您正在修改的项目列表中的TheObject参考到内存中的唯一项目。

你甚至可以创建多个列表,所有列表将包含在内存中,相同的对象引用。


也有一些是你的代码错误:

MyObject TheObject = new MyObject(); 

... 

TheObject = (from o in TheListOfObject 
      where o.ID == SomeParameter 
      select o).SingleOrDefault(); 

你是第一个创建对象的新实例,将影响到TheObject一个新值。

代码的= new MyObject();一部分是无用的。相同= new List<MyObject>();

+0

我想我觉得在函数的开头声明所有的变量对我来说更具可读性;我在做这件事的方式会对性能产生影响吗?替代方案可以是MyObject TheObject = null;这样更好吗? – frenchie 2012-02-16 18:46:00

+0

@frenchie通常不推荐在C#中在方法的开始部分声明变量(在C中为true,但不在C#中)。通常最好将变量**声明为尽可能接近它们的用法**。也就是说,如果你真的想在你的函数开头声明变量,那么'MyObject TheObject = null;'比MyObject TheObject = new MyObject();''MyObject TheObject''好得多。 – ken2k 2012-02-16 19:59:44

+0

好吧,我会用= null在我的代码中进行一些更改;谢谢。 – frenchie 2012-02-17 00:19:53

5

这就要看MyObject是否是一个类或结构。

如果它是一个类,那么您正在修改原始对象。
如果它是一个结构体,你正在修改一个副本。

+0

为什么有人会使用结构班? – frenchie 2012-02-16 15:08:22