我有ObservableCollection
课程和其他属性。
所以看起来有点像这样:
public class A
{
public int Id { get; set; }
...
public object AValue {get; set;}
}
我想克隆这个类的对象。 AValue
属性可以是ObservableCollection
或其他对象。当AValue
是ObservableCollection类型并且我试图向它添加一些对象时,似乎克隆具有与原始相同的对象。如果我只将克隆方法用于AValue
属性,而不是类A
的对象,则可以使用。要克隆我试图使用的对象:
private object Clone(object obj)
{
var t = obj.GetType();
if (obj == null)
return null;
if (t.IsValueType || t == typeof(string))
{
return obj;
}
else if (t.IsGenericType)
{
if (obj is IList)
{
var c= typeof(ObservableCollection<>);
var cType = type.GetGenericArguments().First();
var gType = c.MakeGenericType(cType);
var newC = (IList)Activator.CreateInstance(gType);
foreach (var item in (IEnumerable)obj)
newC.Add(item);
return newC;
}
}
else if (t.IsClass)
{
object objV = Activator.CreateInstance(type);
FieldInfo[] fields = t.GetFields(BindingFlags.Public |
BindingFlags.NonPublic | BindingFlags.Instance);
foreach (FieldInfo field in fields)
{
object fieldV = field.GetValue(obj);
if (fieldValue == null)
continue;
field.SetValue(objV, Clone(fieldV));
}
return obj;
}
throw new ArgumentException("Unknown type");
}
}
修改 谢谢你的回答。 我添加了你的代码@Sefe但它仍然不起作用。我知道其他类型没有克隆,但我想首先使用列表。我不知道哪里出错了。我得到A类对象然后克隆对象并将A类对象发送到对话框。我更改了克隆和原始的集合和属性是相同的。 它应该将IClonable接口添加到通用类型的列表
ObservableCollection<B> = new ObservableCollection<B>();
public class B: Base, ICloneable
{
...
public object Clone()
{
return this.MemberwiseClone();
}
}
泛型类型可以从另一个类继承吗?
答案 0 :(得分:4)
您正在克隆该集合,但您没有克隆其项目。要创建集合的深层克隆,您还需要克隆项目(如果可能):
foreach (var item in (IEnumerable)obj) {
ICloneable cloneable = item as ICloneable;
if (cloneable != null) {
newC.Add(cloneable.Clone());
}
else {
newC.Add(item);
}
}
使用ICloneable
接口是.NET框架中的内置方式,您可以期望framweork方法在必要时识别它。所以这将是首选方式。如果您想重用自己现有的Clone
方法,可以递归调用它:
foreach (var item in (IEnumerable)obj) {
newC.Add(Clone(item));
}
更新(要解决问题的编辑):
当您使用MemberwiseClone
时,所有字段和事件都将转移到克隆。 MemberwiseClone
创建浅副本,因此会传输字段和分配的事件处理程序。因此,如果您的字段包含其他引用类型,则不会克隆这些类型(即使它们是ICloneable
)。此外,分配给orginal的事件处理程序也将分配给克隆。
您的ICloneable.Clone
方法必须注意将克隆置于有效状态。因为什么是有效的不同情况,.NET框架中没有自动深度克隆。调用MemberwiseClone
通常是一个良好的开端,但您必须将包含的对象,事件处理程序等添加到&#34;升级&#34;你的浅层克隆到深层克隆。