c# - 为什么 Object.Equals() 在从不同的程序集实例化时对相同的匿名类型返回 false?

标签 c# .net equality anonymous-types

我有一些代码可以将强类型业务对象映射到匿名类型,然后将其序列化为 JSON 并通过 API 公开。

将我的解决方案重组为单独的项目后,我的一些测试开始失败。我做了一些挖掘,结果是 Object.Equals对来自不同程序集的代码返回的匿名类型的行为不同 - 我不确定为什么,或者我可以做些什么来解决它。

https://github.com/dylanbeattie/AnonymousTypeEquality 有完整的重现代码但实际上破坏的部分在下面。此代码在测试项目中:

[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] - 但我猜测匿名类型的相等性必须考虑完全限定的类型名称,因此将代码移动到不同的程序集中可能会破坏事情。任何人都知道这是如何实现的权威来源/链接?

最佳答案

匿名类型本质上是有范围的。您的示例打破了该范围,因此类型不同。在当前的 C# 编译器中,匿名类型不能超越程序集(或模块,更准确地说)。即使来自两个不同程序集的两个匿名类型具有相同的属性,它们也是两种不同的类型(并且它们是 internal,因此请注意安全隐患)。当您将匿名类型向下转换为 object 时,您知道您做错了。

TL; DR:你在滥用匿名类型。不要惊讶它会咬你。

关于c# - 为什么 Object.Equals() 在从不同的程序集实例化时对相同的匿名类型返回 false?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39250298/

相关文章:

c# - 如何使用 ASP.NET 和 C# 从服务器端确定浏览器类型?

c# - mysql 查询上的 saveFileDialog 文件夹路径

asp.net - Entity Framework 5 在保存时停止运行 T4 模板文件

javafx 如何测试图像是否相等?

c++ - 使用自定义比较函数设置相等性

c# - UWP BitmapImage 到流

c# - 超时执行shell c#

.net - Environment.GetCommandLineArgs - 为什么它是一种方法?为什么不是特性?

android - Kotlin 中的奇怪值比较问题, "==="返回 true 但 "=="返回 false

c# - 如何检查字符串的前两个值