我正在尝试克隆派生类的实例,但不知何故它不能正常工作。克隆方法是:
public static T CloneFieldsAndProperties<T>(T input)
{
T result = (T)Activator.CreateInstance(typeof(T));
PropertyInfo[] listOfProps = typeof(T).GetProperties(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy | BindingFlags.CreateInstance);
FieldInfo[] listOfFields = typeof(T).GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy | BindingFlags.CreateInstance);
foreach (PropertyInfo prop in listOfProps) prop.SetValue(result, prop.GetValue(input, null), null);
foreach (FieldInfo field in listOfFields) field.SetValue(result, field.GetValue(input));
return result;
}
正如您所看到的,我添加了许多BindingFlags
,因为它无效。但无济于事。
在一个简单的情况下工作:
MyclassA1 a1 = new MyclassA1();
MyclassA a = CloneFieldsAndProperties(a1);
if (a is MyclassA1) Text = "Works";
其中:
class MyclassA
{
public int i;
}
class MyclassA1 : MyclassA
{
public int i1;
}
但在我的真实节目中却没有。真正的程序类的声明很长,所以我不会在这里发布它们。可能是什么问题?
答案 0 :(得分:3)
很久以前我也遇到过同样的问题。经过大量的谷歌搜索,对我来说唯一真正的解决方案是对其进行序列化和反序列化。这不是一个糟糕的解决方案,你只会失去一点点性能,就这样做:
将此标记添加到您的班级:
[Serializable()]
public class a
{
}
然后你可以创建一个这样的函数:
public object Clone()
{
IO.MemoryStream mem = new IO.MemoryStream();
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter form = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
form.Serialize(mem, this);
mem.Position = 0;
return form.Deserialize(mem);
}
答案 1 :(得分:2)
如果您需要浅层克隆,只需使用Object.MemberwiseClone
即可。如果您需要深度克隆,请序列化然后反序列化您的对象(例如,使用BinaryFormatter
或DataContractSerializer
)。这将解决诸如周期和交叉引用之类的问题。
答案 2 :(得分:0)
这将起作用,并且可能比序列化方法更快:
<强>代码:强>
using System;
namespace Cloning
{
class Program
{
static void Main(string[] args)
{
Derived d = new Derived() { property = 1, field = 2, derivedProperty = 3, derivedField = 4 };
Base b = new Derived(d);
// Change things in the derived class.
d.property = 5;
d.field = 6;
d.derivedProperty = 7;
d.derivedField = 8;
// Output the copy so you know it's not shallow.
Console.WriteLine((b as Derived).property);
Console.WriteLine((b as Derived).field);
Console.WriteLine((b as Derived).derivedProperty);
Console.WriteLine((b as Derived).derivedField);
Console.ReadLine();
}
class Base
{
public int property { get; set; }
public int field;
}
class Derived : Base
{
public Derived() { }
public Derived(Derived d)
{
// Perform the deep copy here.
// Using reflection should work, but explicitly stating them definitely
// will, and it's not like it's not all known until runtime.
this.property = d.property;
this.field = d.field;
this.derivedProperty = d.derivedProperty;
this.derivedField = d.derivedField;
}
public int derivedProperty { get; set; }
public int derivedField;
}
}
}
<强>测试强>
<强>输出:强>
1
2
3
4
<强>注释:强>
我真的想象这不仅仅是一个微不足道的案例,但可能不是:
public static T CloneFieldsAndProperties<T>(T input)
{
T result = (T)Activator.CreateInstance(input.GetType());
PropertyInfo[] properties = input.GetType().GetProperties();
FieldInfo[] fields = input.GetType().GetFields();
foreach (PropertyInfo property in properties)
property.SetValue(result, property.GetValue(input, null), null);
foreach (FieldInfo field in fields)
field.SetValue(result, field.GetValue(input));
return result;
}