我有类ObservableCollection和其他属性。所以看起来有点像这样:
public class A
{
public int Id { get; set; }
...
public object AValue {get; set;}
}
Run Code Online (Sandbox Code Playgroud)
我想要此类的克隆对象。AValue属性可以是ObservableCollection或其他对象。当AValue类型为ObservableCollection时,我尝试向其中添加一些对象,似乎克隆具有与原始对象相同的对象。如果我仅将克隆方法用于AValueProperty,而不是对类对象使用,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");
}
}
Run Code Online (Sandbox Code Playgroud)
编辑 感谢您的回答。我添加了您的代码@Sefe,但仍然无法正常工作。我知道其他类型不会克隆,但我想先用列表来完成。我不知道哪里出错了。我得到一个A类对象,然后克隆对象并将A类对象发送到对话框。我更改集合,克隆和原始的属性相同。将IClonable接口添加到列表的通用类型就足够了
ObservableCollection<B> = new ObservableCollection<B>();
public class B: Base, ICloneable
{
...
public object Clone()
{
return this.MemberwiseClone();
}
Run Code Online (Sandbox Code Playgroud)
}
泛型类型可以从另一个类继承是否重要?
您正在克隆该集合,但没有克隆它的项目。要创建集合的深层克隆,还需要克隆项目(如果可能):
foreach (var item in (IEnumerable)obj) {
ICloneable cloneable = item as ICloneable;
if (cloneable != null) {
newC.Add(cloneable.Clone());
}
else {
newC.Add(item);
}
}
Run Code Online (Sandbox Code Playgroud)
使用该ICloneable接口是.NET框架的内置方式,您可以期望framweork方法在必要时可以识别它。因此,这将是首选方式。如果您想重用自己的现有Clone方法,则可以递归调用:
foreach (var item in (IEnumerable)obj) {
newC.Add(Clone(item));
}
Run Code Online (Sandbox Code Playgroud)
更新(以解决问题的修改):
使用时MemberwiseClone,所有字段和事件都将转移到克隆中。MemberwiseClone创建浅表副本,因此将传输字段和分配的事件处理程序。因此,如果您的字段包含其他引用类型,则不会克隆这些引用类型(即使它们是ICloneable)。同样,分配给原始对象的事件处理程序也将分配给克隆。
您的ICloneable.Clone方法必须注意将克隆置于有效状态。由于有效情况因情况而异,因此.NET框架中没有自动深度克隆。调用MemberwiseClone通常是一个好的开始,但是您必须先处理包含的对象,事件处理程序等,才能将浅克隆“升级”为深克隆。
| 归档时间: |
|
| 查看次数: |
3955 次 |
| 最近记录: |