我一直想弄清楚为什么有时候我会得到我的数据副本,有时候会得到一个参考。然后我发现了reference types
和value 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()实际上是复制品,但我无法确认。
答案 0 :(得分:3)
非常快,请确保您了解class
和object
之间的区别。 类是cookie切割器; 对象是Cookie。
我认为Ron Beyer(来自评论)在头上发现 - 你可能会说要保持列表同步,以便buffs
一个Ability
object 与另一个Ability
对象保持同步。
只有将一个对象的buff分配给另一个对象时才会有效。
如果你打电话给Add
,那么你将获得对buff的引用,但不会添加新的buff。
您提到了价值与参考类型;快速列表如下(有人跳到这里并纠正我)
值类型
参考类型
您应该注意一个案例:
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
的所有更改都将指向此新变量(这将是退出函数的范围后,从堆中清除。)
希望有所帮助!