C# Silverlight扩展方法中使用反射的深度复制?

C# Silverlight扩展方法中使用反射的深度复制?,c#,silverlight,reflection,silverlight-5.0,deep-copy,C#,Silverlight,Reflection,Silverlight 5.0,Deep Copy,因此,我试图找到一种通用的扩展方法,使用反射创建对象的深度副本,这种方法可以在Silverlight中工作。在Silverlight中,使用序列化的深度复制不是很好,因为它在部分信任中运行,并且BinaryFormatter不存在。我也知道反射比克隆的序列化更快 如果有一个方法可以复制公共、私有和受保护的字段,并且是递归的,这样它就可以复制对象中的对象,还可以处理集合、数组等 我在网上搜索过,只能找到使用反射的浅拷贝实现。我不明白为什么,因为您可以只使用MemberwiseClone,所以对我来

因此,我试图找到一种通用的扩展方法,使用反射创建对象的深度副本,这种方法可以在Silverlight中工作。在Silverlight中,使用序列化的深度复制不是很好,因为它在部分信任中运行,并且BinaryFormatter不存在。我也知道反射比克隆的序列化更快

如果有一个方法可以复制公共、私有和受保护的字段,并且是递归的,这样它就可以复制对象中的对象,还可以处理集合、数组等

我在网上搜索过,只能找到使用反射的浅拷贝实现。我不明白为什么,因为您可以只使用MemberwiseClone,所以对我来说,这些实现是无用的


谢谢。

您不能只使用常规的.NET反射吗?将对象序列化为
内存流
,然后将其反序列化回来。这将创建一个深度副本(最终使用反射),您几乎不需要任何代码:

T DeepCopy<T>(T instance)
{
  BinaryFormatter formatter=new BinaryFormatter();

  using(var stream=new MemoryStream())
  {
    formatter.Serialize(stream, instance);
    stream.Position=0;

    return (T)formatter.Deserialize(stream);
  }
}
T DeepCopy(T实例)
{
BinaryFormatter formatter=新的BinaryFormatter();
使用(var stream=new MemoryStream())
{
序列化(流、实例);
流位置=0;
返回(T)格式化程序。反序列化(流);
}
}
所需的名称空间:

using System.Reflection;
using System.Collections.Generic;
方法:

    private readonly static object _lock = new object();

    public static T cloneObject<T>(T original, List<string> propertyExcludeList)
    {
        try
        {
            Monitor.Enter(_lock);
            T copy = Activator.CreateInstance<T>();
            PropertyInfo[] piList = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            foreach (PropertyInfo pi in piList)
            {
                if (!propertyExcludeList.Contains(pi.Name))
                {
                    if (pi.GetValue(copy, null) != pi.GetValue(original, null))
                    {
                        pi.SetValue(copy, pi.GetValue(original, null), null);
                    }
                }
            }
            return copy;
        }
        finally
        {
            Monitor.Exit(_lock);
        }
    }
propertyExcludeList参数是要从副本中排除的属性名称列表,如果要复制所有属性,只需传递一个空列表,例如

new List<string>()
新列表()

对于数据协定对象,我们在Silverlight中使用了以下帮助器方法进行深度克隆:

public static T Clone<T>(T source)
        {

            DataContractSerializer serializer = new DataContractSerializer(typeof(T));
            using (MemoryStream ms = new MemoryStream())
            {
                serializer.WriteObject(ms, source);
                ms.Seek(0, SeekOrigin.Begin);
                return (T)serializer.ReadObject(ms);
            }
        }
公共静态T克隆(T源)
{
DataContractSerializer serializer=新的DataContractSerializer(typeof(T));
使用(MemoryStream ms=new MemoryStream())
{
serializer.WriteObject(ms,source);
Seek女士(0,SeekOrigin.Begin);
return(T)serializer.ReadObject(ms);
}
}
这样使用:

var clone = CloneHelper.Clone<MyDTOType>(dtoVar);
var clone=CloneHelper.clone(dtoVar);

否,Silverlight中不存在BinaryFormatter。这不适用于用户控件,如不可序列化对象!我得到了
System.ArgumentException未被用户代码Message=未找到属性集方法处理。
这是一个浅层副本。它需要是递归的,并且要检查属性是否是深度副本的集合。这是基于序列化的,它能在不可序列化的类上工作吗?快速提问,这是如何处理数组和列表的?它是否复制数组/列表的引用?还是在新引用下重建数组/列表?换句话说,如果带列表的类A复制到B,编辑B是否也会编辑A的列表?
var clone = CloneHelper.Clone<MyDTOType>(dtoVar);