【问题标题】:Reference of object in array not kept未保留数组中对象的引用
【发布时间】:2015-04-01 07:49:29
【问题描述】:

如果对列表中对象的引用丢失,我遇到了问题,这就是我详细阐述我的代码的方式:

PropertyObject[] myProperties = new PropertyObject[200];
var objParent = new Parent();
var objProperty = new PropertyObject();

myProperties[0] = objProperty;
objParent.property = myProperties[0];

现在当我修改objParent.property 时,它不会修改myProperties 数组中的对象,有什么解决方法吗?我需要这个,这样我就不必遍历数组。

这就是我修改对象的方式:

public void modifyObject(ref Parent objectToModify) {
   objectToModify.property.isThisCrazy = true;
}

然后我只调用modifyObject 方法。

【问题讨论】:

  • PropertyObject 是什么?
  • 它是一个结构体,用来保存对象的一些特征
  • objParent不在数组中,那么修改objParent为什么要改变数组呢? “那我就调用 modifyObject 函数”在哪里?
  • 结构是值类型。要使其成为引用类型,请将其更改为类

标签: c# arrays struct reference


【解决方案1】:

structs 是不可变的。将 struct 分配给另一个变量将导致 struct 被复制。

在一个实例上分配属性时,struct 的另一个实例的属性不会更改。因此,您在其他参考资料中看不到更新。

演示结构问题的示例代码:

struct X
{
    public string Y { get; set; }

    public X(string y) : this()
    {
        Y = y;
    }
}

X x = new X("abc");
X x2 = x;

x2.Y = "def";

Console.WriteLine(x.Y);
Console.WriteLine(x2.Y);

对于您希望 x.Yx2.Y 相同的类,但对于结构不同。

【讨论】:

  • 结构并非天生不可变。它们的复制语义使可变结构难以使用。因此,建议它们是不可变的,但很可能具有可变结构。
  • @mikez:同意。稍微更新了第一句话。
  • 你:实际上你是在设置属性/字段时创建新实例。不。新实例是在你将结构分配给另一个变量(或传递它)时创建的作为方法的值参数,或将其装箱)。在您的示例中,X x2 = x; 行创建了一个新实例。设置属性Y 的值不会创建结构的新实例!
  • @JeppeStigNielsen:你是对的。感谢您指出了这一点。更新了我的帖子。
【解决方案2】:

您写道“对对象的引用”丢失了,但 struct 没有对它的“引用”。

struct 具有值类型语义。因此,当您使用= 分配时,会制作右侧的副本。你这样做:

myProperties[0] = objProperty;

复制该值,并将副本放入数组的第 0 个条目中。

如果您稍后修改“原始”实例objProperty,则该更改将不会出现在数组中保存的副本中。

这并不是真正的数组问题。所有struct 值分配都会发生同样的情况。例如:

var objProperty2 = objProperty;

如果原来的 objProperty 之后发生了变异,复制的值 objProperty2 将不受影响。参见例如C# Reference type assignment VS value type assignment

有些人认为可变结构是邪恶的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-26
    • 1970-01-01
    • 1970-01-01
    • 2013-11-06
    相关资源
    最近更新 更多