c# - c# 中的字符串相等运算符 ==

标签 c# string operator-overloading equality

我试图查看在 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);
}

我不知道是不是 Reflector 在捉弄我,但是当我尝试为我自己的类实现这个策略时,我在 Equals 和重载的 == 运算符之间出现了无限循环(正如预期的那样) .字符串类有什么不同还是我的 Reflector 正在报告

static Equals(object o1, object o2)

将 Object 类作为 String 类的一部分的方法?

最佳答案

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

您在代码中可能犯的错误是您没有将类实例转换为 object在评估 == 之前运算符(operator)。

假设您有:

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 的基类)。您的反射器可能会或可能不会根据其设置显示继承的方法。

在您发布的代码中,由于 objA 的声明类型和 objBobject ,然后是带有 object 的运算符无论实例的实际类型如何,都会调用参数。

更新2:您更新后的代码似乎确实包含无限递归。我认为这可能是反射器工具中的错误。

更新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 定义为“如果两个无符号整数值不相等(无符号值),则在指定偏移处分支到目标指令,缩写形式。”

因此,看来毕竟是在执行引用相等。

关于c# - c# 中的字符串相等运算符 ==,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9317737/

相关文章:

c# - ASP.NET Core错误:System.TypeLoadException:无法加载类型 'Microsoft.AspNetCore.WebUtilities.FileBufferingWriteStream'

c# - mscorlib.dll 中发生奇怪的错误 'System.ExecutionEngineException'

python - 在 Python 中合并由空格分隔的字符串

java - 用逗号拆分字符串,但忽略括号或引号中的逗号

c++ - 运算符重载 : Simple Addition. .. 错误 C2677:二进制 '+':未找到具有类型 ___ 的全局运算符(或没有可接受的转换)

c# - 使用 rowdatabound 计算列数

c# - Buffer.BlockCopy 与不安全字节 * 指针复制

javascript - 如何计算 javascript 中字符串末尾的换行符数量?

c++ - 参数化运算符重载

c++ - std::cin 中的运算符 >> 不匹配