为什么要复制类而不是引用?

时间:2015-10-01 01:43:04

标签: c# value-type reference-type

我一直想弄清楚为什么有时候我会得到我的数据副本,有时候会得到一个参考。然后我发现了reference typesvalue types。所以我的生活发生了变化,我在编码时开始使用这些信息。

现在我在Unity中制作自定义编辑器。我有一个Ability类,其中包含一个Buff列表(Buff类列表)。所以我拥有的每项技能都可以包含多个buff。

在编辑数据库中的能力变量时,我首先获得我正在使用的能力的副本,不用直接编辑它们,而是编辑副本,然后在完成后将副本保存到数据库中。但是我似乎仍然用一行而不是另一行复制。所以现在我似乎没有引用引用类型,但使其行为类似于值类型。我不明白为什么会这样。

//This constructor is used to make a copy of an existing Ability in the database
public Ability(Ability cloneFrom)
{
    buffs = new List<Buff>();

    //This will work, not cause a reference but actually takes a copy.
    //I don't understand that because I am using Add()on a class (reference type)
    for (int x = 0; x < cloneFrom.buffs.Count; x++)
        buffs.Add(cloneFrom.buffs[x]);

    //This will create a reference as expected
    buffData = cloneFrom.buffData;
}

我唯一能想到的是List.Add()实际上是复制品,但我无法确认。

1 个答案:

答案 0 :(得分:3)

非常快,请确保您了解classobject之间的区别。 是cookie切割器; 对象是Cookie。

我认为Ron Beyer(来自评论)在头上发现 -​​ 你可能会说要保持列表同步,以便buffs一个Ability object 与另一个Ability对象保持同步。

只有将一个对象的buff分配给另一个对象时才会有效。

如果你打电话给Add,那么你将获得对buff的引用,但不会添加新的buff。

您提到了价值与参考类型;快速列表如下(有人跳到这里并纠正我)

值类型

  • 原始类型(int,float,long,double,bool等)
  • 结构
  • 枚举

参考类型

  • 代表
  • 接口
  • 物体

您应该注意一个案例:

public class Ability {
    public int Score { get; set; }

    public Ability(int score) {
        Score = score;
    }
}


public static void KillReference(Ability ability) {
    // When we execute the next line, the ability
    // from the original scope will stay the same
    ability = new Ability(2);
}

public static void Main() {
    Ability ability = new Ability(5);

    KillReference(ability);

    // ability.Score is still 5
}

<强> OHGODWHY

当你将一个引用类型传递给一个函数时,你实际上传递了一个引用的“副本”(这与C / C ++中的指针相同)...你有效地传递一个引用值(令人困惑,对吗?)。

当您将该引用分配给另一个对象时,此变量不再引用所引用的原始对象 - 这是一个新变量,对ability的所有更改都将指向此新变量(这将是退出函数的范围后,从堆中清除。)

希望有所帮助!