3

そこで、Silverlightで機能する、リフレクションを使用してオブジェクトのディープコピーを作成する汎用拡張メソッドを見つけようとしています。シリアル化を使用したディープコピーは、部分的に信頼されて実行され、BinaryFormatterが存在しないため、Silverlightではそれほど優れていません。また、クローン作成のシリアル化よりもリフレクションの方が高速であることも知っています。

public、private、およびprotectedフィールドをコピーするように機能し、オブジェクト内のオブジェクトをコピーできるように再帰的であり、コレクションや配列なども処理できるメソッドがあると便利です。

私はオンラインで検索しましたが、リフレクションを使用した浅いコピーの実装しか見つけることができません。MemberwiseCloneを使用できるので、理由がわかりません。そのため、私にとって、これらの実装は役に立たないのです。

ありがとうございました。

4

3 に答える 3

3

データコントラクトオブジェクトの場合、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);
            }
        }

このように使用されます:

var clone = CloneHelper.Clone<MyDTOType>(dtoVar);
于 2012-11-20T13:30:45.613 に答える
3

必要な名前空間:

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

これはSilverlightに固有のものではなく、単なるReflectionです。

記述されているように、パラメーターのないコンストラクターを持つオブジェクトでのみ機能します。コンストラクターパラメーターを必要とするオブジェクトを使用するには、パラメーターを含むobject []を渡し、Activator.CreateInstanceメソッドの別のオーバーロードを使用する必要があります。

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

propertyExcludeListパラメーターは、コピーから除外するプロパティ名のリストです。すべてのプロパティをコピーする場合は、空のリストを渡すだけです。

new List<string>()
于 2012-11-02T16:58:10.160 に答える
2

通常の.NETリフレクションだけを使用することはできませんか?オブジェクトをにMemoryStreamシリアル化してから、逆シリアル化します。これにより、(最終的にはリフレクションを使用して)ディープコピーが作成され、コードはほとんど必要ありません。

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);
  }
}
于 2012-11-02T16:31:15.417 に答える