Deep Copy using Reflection in an Extension Method for Silverlight?

霸气de小男生 提交于 2020-01-10 00:27:28

问题


So I'm trying to find a generic extension method that creates a deep copy of an object using reflection, that would work in Silverlight. Deep copy using serialization is not so great in Silverlight, since it runs in partial trust and the BinaryFormatter does not exist. I also know that reflection would be faster then serialization for cloning.

It would be nice to have a method that works to copy public, private and protected fields, and is recursive so that it can copy objects in objects, and that would also be able to handle collections, arrays, etc.

I have searched online, and can only find shallow copy implementations using reflection. I don't understand why, since you can just use MemberwiseClone, so to me, those implementations are useless.

Thank You.


回答1:


For data contract objects we have used the following helper method for deep cloning within 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);
            }
        }

Used like this:

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



回答2:


Required Namespaces:

using System.Reflection;
using System.Collections.Generic;

Method:

    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);
        }
    }

This is not specific to Silverlight in any way - it is just plain Reflection.

As written it will only work with objects that have a parameterless constructor. To use objects that require constructor parameters, you will need to pass in an object[] with the parameters, and use a different overload of the Activator.CreateInstance method e.g.

T copy = (T)Activator.CreateInstance(typeof(T), initializationParameters);

The propertyExcludeList parameter is a list of property names that you wish to exclude from the copy, if you want to copy all properties just pass an empty list e.g.

new List<string>()



回答3:


Can't you just use regular .NET reflection? Serialize your object to a MemoryStream and then deserialize it back. This will create a deep copy (ultimately using reflection) and will require hardly any code on your part:

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);
  }
}


来源:https://stackoverflow.com/questions/13198658/deep-copy-using-reflection-in-an-extension-method-for-silverlight

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!