3

設計上、リモート アセンブリに由来するオブジェクトのクラスがいくつかあります。インスタンスが異なるアセンブリからロードされた場合でも、これらのクラスのインスタンスが等しいかどうかを比較できるようにしたいと考えています。実際には、これらはネットワークの場所または Web から読み込まれ、ローカル キャッシュと比較したいと思います。シリアライゼーションとカスタム シリアライゼーション バインダーを使用するソリューションから、いくつかの良い結果が得られました。

比較に使用しているサンプル クライアント コードは次のとおりです。

    Assembly a = Assembly.LoadFile(@"c:\work\abc1\abc.dll");
    Type t1 = a.GetType("Abc.Def");
    Assembly b = Assembly.LoadFile(@"c:\work\abc2\abc.dll");
    Type t2 = b.GetType("Abc.Def");
    Object o1 = t1.GetConstructors()[0].Invoke(null);
    Object o2 = t2.GetConstructors()[0].Invoke(null);
    Console.WriteLine(o1.Equals(o2));

アセンブリで使用しているパターンは次のとおりです。

namespace Abc
{
    internal sealed class DefBinder : SerializationBinder
    {
        public override Type BindToType(string assemblyName, string typeName)
        {
            Type ttd = null;
            try
            {
                ttd = this.GetType().Assembly.GetType(typeName);
            }
            catch (Exception any)
            {
                Debug.WriteLine(any.Message);
            }
            return ttd;
        }
    }


    [Serializable]
    public class Def
    {
        public Def()
        {
            Data = "This is the data";
        }
        public String Data { set; get; }
        public override bool Equals(object obj)
        {
            if (obj.GetType().FullName.Equals(this.GetType().FullName))
            {
                try
                {
                    BinaryFormatter bf = new BinaryFormatter();
                    System.IO.MemoryStream ms = new System.IO.MemoryStream();
                    bf.Serialize(ms, obj);
                    ms.Seek(0, System.IO.SeekOrigin.Begin);
                    bf.Binder = new Abc.DefBinder();
                    Abc.Def that = (Abc.Def)bf.Deserialize(ms);
                    if (this.Data.Equals(that.Data))
                    {
                        return true;
                    }
                }
                catch (Exception any) {
                    Debug.WriteLine(any.Message);
                }
            }
            return false;
        }
    }
}

私の質問は次のとおりです:これは機能しているように見えますが、ハッキーに感じます。異なるアセンブリからロードされる可能性のあるオブジェクトを比較するより直接的な方法はありますか?

4

1 に答える 1

1

これはややハックですが、作業を完了するための迅速かつ簡単な方法です。他にできることは、多くのリフレクションを使用して、指定された 2 つの型の等価メソッドを作成することです。何かのようなもの:

public bool Equals(Type t1, Type t2)
{
    var t1Constructors = t1.GetConstructors();
    var t2Constructors = t2.GetConstructors();
    //compare constructors
    var t1Methods = t1.GetMethods();
    var t2Methods = t2.GetMethods();
    //compare methods
    //etc.
}

BindingFlags を使用してプロパティ/メソッド/などを取得します。あなたが気にかけ、それぞれが等しいかどうかを調べます。確かに簡単ではありませんが、特定のユースケースで「平等」が実際に何を意味するかを決定する際に、多くの柔軟性が得られます。

于 2012-11-21T20:29:01.167 に答える