3

我有一些对象类,这些对象在设计上应该源自远程程序集。我希望能够比较这些类的实例是否相等,即使这些实例是从不同的程序集加载的。在现实生活中,这些将从网络位置或网络加载,我想与本地缓存进行比较。我从使用序列化和自定义序列化绑定器的解决方案中获得了一些好的结果。

我用来进行比较的示例客户端代码是:

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

我的问题是:这似乎可行,但感觉很hacky,所以有没有更直接的方法来比较可能从不同程序集中加载的对象?

4

1 回答 1

1

这有点笨拙,但它是完成工作的一种快速简便的方法。您可以做的另一件事是使用大量反射为两个给定类型编写相等方法。就像是:

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 回答