我有一些代码将强类型业务对象映射为匿名类型,然后将其序列化为JSON并通过API公开。
将我的解决方案重组为单独的项目后,我的一些测试开始失败。我做了一些挖掘,结果发现Object.Equals
在匿名类型上的行为有所不同,这些匿名类型是由来自不同程序集的代码返回的-我不确定为什么,或者我可以做些什么来解决。
https://github.com/dylanbeattie/AnonymousTypeEquality上有完整的repro代码,但实际中断的位置在下面。这段代码在Tests项目中:
[TestFixture]
public class Tests {
[Test]
public void BothInline() {
var a = new { name = "test", value = 123 };
var b = new { name = "test", value = 123 };
Assert.That(Object.Equals(a,b)); // passes
}
[Test]
public void FromLocalMethod() {
var a = new { name = "test", value = 123 };
var b = MakeObject("test", 123);
Assert.That(Object.Equals(a, b)); // passes
}
[Test]
public void FromOtherNamespace() {
var a = new { name = "test", value = 123 };
var b = OtherNamespaceClass.MakeObject("test", 123);
Assert.That(Object.Equals(a, b)); // passes
}
[Test]
public void FromOtherClass() {
var a = new { name = "test", value = 123 };
var b = OtherClass.MakeObject("test", 123);
/* This is the test that fails, and I cannot work out why */
Assert.That(Object.Equals(a, b));
}
private object MakeObject(string name, int value) {
return new { name, value };
}
}
然后解决方案中有一个单独的类库,其中仅包含以下内容:
namespace OtherClasses {
public static class OtherClass {
public static object MakeObject(string name, int value) {
return new { name, value };
}
}
}
根据MSDN的说法,“只有匿名属性的两个实例的所有属性都相等时,它们的两个实例才相等。” (我的重点)-那么出于比较的目的,是什么控制两个实例的是否具有相同的匿名类型?我的两个实例具有相等的哈希码,并且都看起来像是
<>f__AnonymousType0`2[System.String,System.Int32]
-但我猜想匿名类型的相等性必须考虑完全限定的类型名称,因此将代码移到不同的程序集中可能会破坏事情。任何人都确切地知道如何实现此目标的源/链接? 最佳答案
如果使用Reflector之类的工具反汇编程序集,您将看到匿名类型由每个程序集中的类表示,如下所示(在取消编译器生成的标识符之后):
internal sealed class AnonymousType<TName, TValue>
{
private readonly TName _name;
private readonly TValue _value;
public TName name => this._name;
public TValue value => this._value;
public AnonymousType(TName name, TValue value)
{
this._name = name;
this._value = value;
}
public override bool Equals(object value)
{
var that = value as AnonymousType<TName, TValue>;
return that != null &&
EqualityComparer<TName>.Default.Equals(this._name, that._name) &&
EqualityComparer<TValue>.Default.Equals(this._value, that._value);
}
public override int GetHashCode()
{
// ...
}
}
Equals
方法的第一行检查value
是否为AnonymousType<TName, TValue>
的实例,专门引用当前程序集中定义的类。因此,来自不同程序集的匿名类型即使具有相同的结构,也永远不会比较相等。您可能需要更改测试以比较对象的序列化JSON,而不是对象本身。
关于c# - 当从不同程序集中实例化相同的匿名类型时,为什么Object.Equals()对于相同的匿名类型返回false?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39250298/