我有一个有趣的问题。我有一个班级人员:
public class Person
{
public string Name { get; set; }
public int? Score { get; set; }
public int NbrOfWins { get; set; }
public int NbrOfLosses { get; set; }
public int HighScore { get; set; }
}
我创建了一个Observable集合:
ObservableCollection<Person> test = new ObservableCollection<Person>();
我有一个扩展方法可以添加到observable集合中:
public static void myFillTest<T>(this ObservableCollection<T> value1, T value2, int nbr)
{
for (int x = 0; x < nbr; x++)
{
value1.Add(value2);
}
}
我在这个集合中添加了5个项目:
test.myFillTest(new Person { Name = "None" }, 5);
如果我在一个实例中更改名称:
test[2].Name = "John";
集合中的所有项目都会发生变化,就好像它们都指向同一个东西一样。 这会是什么原因?顺便说一下,这适用于int类型的T和字符串,但不适用于类型类。
答案 0 :(得分:4)
这是因为类Person是引用类型,而整数是值类型。当你添加相同的int 5次时,它被复制,当你添加5次时,它的一个实例被添加到5个不同的索引。您可以在此处阅读有关参考类型http://msdn.microsoft.com/en-us/library/490f96s2.aspx的信息。如果希望它按预期工作,则需要复制person类型的对象。
您可以将代码更改为以下内容,以便始终创建新对象:
public static void MyFillTest<T>(this ObservableCollection<T> value1, T value2, int nbr)
{
for (int x = 0; x < nbr; x++)
{
if (typeof(T).IsValueType)
{
value1.Add(value2);
}
else
{
if (value2 is ICloneable)
{
ICloneable cloneable = (ICloneable)value2;
value1.Add((T)cloneable.Clone());
}
}
}
}
public class Person : ICloneable
{
public string Name { get; set; }
public int? Score { get; set; }
public int NbrOfWins { get; set; }
public int NbrOfLosses { get; set; }
public int HighScore { get; set; }
#region ICloneable Members
public object Clone()
{
return new Person
{
Name = this.Name,
Score = this.Score,
NbrOfWins = this.NbrOfWins,
NbrOfLosses = this.NbrOfLosses,
HighScore = this.HighScore
};
}
#endregion
}
答案 1 :(得分:2)
当您调用方法时,新人{Name =“None”}仅实例化一次。所以他们都引用同一个对象。
答案 2 :(得分:2)
这很简单 - 您要将value2
添加到集合nbr
次。或者更确切地说,在添加对象时(就像在您的示例中一样),您将引用添加到同一对象nbr
次。因此,如果您更改一个,则将其全部更改。
答案 3 :(得分:1)
此扩展方法将执行您要执行的操作:
public static void myFillTest<T>(this ObservableCollection<T> value1, Action<T> init, int nbr) where T: new()
{
for (int x = 0; x < nbr; x++)
{
var value2 = new T();
init(value2);
value1.Add(value2);
}
}
这样称呼:
test.myFillTest(p => p.Name = "None", 5);
答案 4 :(得分:0)
Person对象被实例化一次,其引用被使用了5次。您可以通过使用成员克隆来创建原始对象的浅副本来克服这个问题。