C# 通过具有特殊约束的反射克隆对象

C# 通过具有特殊约束的反射克隆对象,c#,reflection,C#,Reflection,假设一个对象具有此属性 public int? Prop1 { get; set; } public string Prop2 { get; set; } public EntityCollection<X> Prop3 { get; set; } public EntityCollection<Y> Prop4 { get; set; } public EntityCollection<Z> Prop5 { get; set; } 但是我不知道如何将pro

假设一个对象具有此属性

public int? Prop1 { get; set; }
public string Prop2 { get; set; }
public EntityCollection<X> Prop3 { get; set; }
public EntityCollection<Y> Prop4 { get; set; }
public EntityCollection<Z> Prop5 { get; set; }
但是我不知道如何将
prop3
prop4
prop5
复制到另一个对象上

编辑: 我应该不要
序列化
对象!我做这项工作是因为我的对象有大数据,通过这个技巧我可以复制一些数据


如果我说这个问题的根源,这很有趣!我使用
EF
作为
ORM
并通过
WCF
Silverlight
客户端中使用数据对象。当我在
WCF
中发送
List
时,它会发送
List
及其关系数据!!客户死了

我要做的是使对象
可序列化
。然后可以在内存中序列化该对象,并将其反序列化为新的克隆对象

我有两个功能:

    public static MemoryStream ToMemoryStream(object entity)
    {
        MemoryStream ms = new MemoryStream();
        BinaryFormatter formatter = new BinaryFormatter();

        formatter.Serialize(ms, entity);
        return ms;
    }

    public static T FromMemoryStream<T>(Stream stream)
    {
        BinaryFormatter formatter = new BinaryFormatter();
        stream.Position = 0;
        return (T)formatter.Deserialize(stream);
    }
公共静态内存流到内存流(对象实体)
{
MemoryStream ms=新的MemoryStream();
BinaryFormatter formatter=新的BinaryFormatter();
序列化(ms、实体);
返回ms;
}
来自MemoryStream(流)的公共静态T
{
BinaryFormatter formatter=新的BinaryFormatter();
流位置=0;
返回(T)格式化程序。反序列化(流);
}
像这样和你的班级在一起

[Serializable]
public class MyClass 
{
    public int? Prop1 { get; set; }
    public string Prop2 { get; set; }
    public EntityCollection<X> Prop3 { get; set; }
    public EntityCollection<Y> Prop4 { get; set; }
    public EntityCollection<Z> Prop5 { get; set; }
}
[可序列化]
公共类MyClass
{
公共int?Prop1{get;set;}
公共字符串Prop2{get;set;}
公共EntityCollection Prop3{get;set;}
公共EntityCollection Prop4{get;set;}
公共EntityCollection Prop5{get;set;}
}
现在可以将该类序列化到内存中,并从中创建克隆

public MyClass Clone()
{
    var myclass = new MyClass();
    /* Do Some init */

    var ms = ToMemoryStream(myclass);

    var myNewObject = FromMemoryStream<MyClass>(ms);
    return myNewObject;
}
publicMyClass克隆()
{
var myclass=新的myclass();
/*做一些初始化*/
var ms=多模流(myclass);
var myNewObject=FromMemoryStream(毫秒);
返回myNewObject;
}

您必须替换以下行

  fromField.SetValue(toRecord, 
                           fromField.GetValue(fromRecord, null), 
                           null);
有了这些声明

        if (typeof(IList).IsAssignableFrom(t.PropertyType))
        {
            IList fromList = fromField.GetValue(fromRecord, null);
            IList toList = fromField.GetValue(toRecord, null);
            foreach (var item in fromList)
                toList.Add(item);
        }
        else
        {
            fromField.SetValue(toRecord,
                               fromField.GetValue(fromRecord, null),
                               null);
        }

您必须将IList替换为某个合适的接口,可能是ICollection或其他可以与EntityCollection一起使用的接口,我没有任何东西要测试,所以我刚刚发布了这个示例。

请记住,在这个示例中,X、Y和Z也应该是可序列化的。
。您关于不使用序列化的观点我不理解;如果你想克隆一个大的图(“大数据”),你将有2个大的图形——中间的序列化看起来是不真实的。@ Marc Gravell:只需通过ErrutsOrth.Trand复制一个带有EntyType类型的属性。因此,要么您想要一个深度克隆(在这种情况下序列化应该可以工作,并且您将拥有两倍的数据),要么您想要一个实体集合的副本(因此只需调用
SetValue
)-我仍然不清楚问题出在哪里。如何使用EntityCollection类型反映属性
        if (typeof(IList).IsAssignableFrom(t.PropertyType))
        {
            IList fromList = fromField.GetValue(fromRecord, null);
            IList toList = fromField.GetValue(toRecord, null);
            foreach (var item in fromList)
                toList.Add(item);
        }
        else
        {
            fromField.SetValue(toRecord,
                               fromField.GetValue(fromRecord, null),
                               null);
        }