我有一些对象类,它们应该设计来自远程程序集。我希望能够比较这些类的实例是否相等,即使实例是从不同的程序集加载的。在现实生活中,这些将从网络位置或网络加载,我想与本地缓存进行比较。我从使用序列化和自定义序列化活页夹的解决方案中获得了一些好的结果。
我用来进行比较的示例客户端代码是:
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;
}
}
}
我的问题是:这似乎有效,但感觉很乱,所以是否有更直接的方法来比较可能从不同程序集加载的对象?
答案 0 :(得分: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获取属性/方法/等。你关心并检查每个人的平等。当然不是很容易,但它会给你很大的灵活性来决定什么"平等"真的意味着你的具体用例。