为什么 class 被复制而不是被引用?

Why is class copied instead of referenced?

一段时间以来,我一直在努力弄清楚为什么我有时会得到一份数据副本,有时会得到一份参考资料。然后我发现了 reference typesvalue types。所以我的生活改变了,我开始在编码时使用这些信息。

现在我正在 Unity 中制作自定义编辑器。我有一个 Ability class,其中包含一个 Buff 列表(增益列表 classes)。所以我拥有的每个能力都可以包含多个增益。

在数据库中编辑能力变量时,我首先获取我正在使用的能力的副本,而不是直接编辑它们而是编辑副本,然后在完成后将副本保存到数据库中。然而,我似乎仍然用一行而不是另一行来复印。所以现在看来​​我不是在引用引用类型,而是让它表现得像一个值类型。我不明白这是为什么。

//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() 确实进行了复制,但我无法确认。

非常快,确保您了解 classobject 之间的区别。 class 是千篇一律; 对象 是 cookie。

我认为 Ron Beyer(从评论中)一针见血——你可能是说你想保持列表同步,这样一个 Abilitybuffs 对象与另一个Ability对象保持同步。

这只有在您将一个对象的增益分配给另一个对象时才有效。

如果您调用 Add,您将获得对增益的引用,但不会添加新的增益。

您提到了值类型与引用类型;快速列表如下(有人跳在这里纠正我)

值类型

  • 基本类型(int、float、long、double、bool 等)
  • 结构
  • 枚举

引用类型

  • classes
  • 代表
  • 接口
  • 对象

有一种情况你应该知道:

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

当您将引用类型传递给函数时,您实际上是在传递一个 "copy" 引用(这与 C/C++ 中的指针相同)...重新有效地按值传递引用(令人困惑,对吧?)。

当您将该引用分配给另一个对象时,被引用的原始对象不再被该变量引用——有一个新变量,对 ability 的所有更改都将针对该新变量(一旦你退出函数的范围,它将从堆中清除。

希望对您有所帮助!