字符串等式运算符==在c#中

我试图在C#中查看为字符串类中的比较运算符实现的代码。 发现是这样的:

//THIS IS NOT WHAT I MEANT public static bool Equals(object objA, object objB) { return ((objA == objB) || (((objA != null) && (objB != null)) && objA.Equals(objB))); } //THIS IS WHAT I SEE REALLY and the above is what I would expect to see public static bool Equals(string a, string b) { return ((a == b) || (((a != null) && (b != null)) && EqualsHelper(a, b))); } public static bool operator ==(string a, string b) { return Equals(a, b); } 

我不知道reflection器是否在玩我的技巧,但是当我尝试为我自己的类实现这个策略时,我在Equals和重载的==运算符之间得到了一个无限循环(如预期的那样)。 在字符串类中是否有不同或者是我的Reflector正在报告

 static Equals(object o1, object o2) 

Object类上的方法是String类的一部分吗?

C#中的等式运算符不是多态的。 当你评估objA == objB ,你实际上是在执行==(object a, object b)运算符实现(它检查引用相等性),而不是==(string a, string b) ,因为声明的类型是objAobjB变量是object ,而不是string

您在代码中可能犯的错误是,在对它们求值==运算符之前,您没有将类实例转换为object

假设你有:

 public static bool Equals(MyClass objA, MyClass objB) { return objA == objB || objA != null && objB != null && objA.Equals(objB); } 

…你需要用以下代替它:

 public static bool Equals(MyClass objA, MyClass objB) { return (object)objA == (object)objB || objA != null && objB != null && objA.Equals(objB); } 

……相当于:

 public static bool Equals(MyClass objA, MyClass objB) { return object.ReferenceEquals(objA, objB) || objA != null && objB != null && objA.Equals(objB); } 

更新String类包含static bool Equals(string a, string b)方法 static bool Equals(object a, object b)方法。 区别在于前者是在String类本身中定义的,而后者是从Object类( String的基类)inheritance的。 您的reflection器可能会也可能不会根据其设置显示inheritance的方法。

在您发布的代码中,由于声明的objAobjB类型是object ,因此无论实例的实际类型如何,都将调用具有object参数的运算符。

更新2 :您更新的代码确实包含无限递归。 我认为它可能是reflection器工具中的一个错误。

更新3 :这似乎是拆解中的错误。 实现Equals(string a, string b)运算符的第一个条件在反汇编的C#代码中显示为a == b 。 但是,IL代码的前几行实际上是:

 ldarg.0 ldarg.1 bne.un.s IL_0006 ldc.i4.1 ret 

bne.un.s定义为“如果两个无符号整数值不相等(无符号值),则为指定偏移量的目标指令的分支,短格式。”

因此,似乎正在执行参考相等。

没有String.Equals(object, object)方法。
你看到了Object.Equals

它没有递归的原因是objA == objB调用内置对象相等运算符,而不是自定义字符串相等运算符。
(根据操作数的编译时类型解析运算符重载)

一个不那么令人困惑的解决方案:不要使用==运算符:

 public static bool Equals(MyClass a, MyClass b) { return ReferenceEquals(a, b) || ((!ReferenceEquals(a, null) && !ReferenceEquals(b, null)) && a.Equals(b))); } 

它引用的equals方法是这样的:

 public static bool Equals(string a, string b) { /* == is the object equals- not the string equals */ return a == b || (a != null && b != null && string.EqualsHelper(a, b)); } public static bool operator ==(string a, string b) { return string.Equals(a, b); } 

即一个等于两个字符串而不是两个对象的方法。