首页 > 解决方案 > 如何选择运算符 ==?

问题描述

internal static class ChoosingEqOperTest
{
    class A
    {
        public static bool operator ==(A a, A a2) => false;
    }

    class B:A
    {
        public static bool operator ==(B a, B a2) => true;
    }

    static void CheckChosenOper<T>(T x, T x2) where T : A
    {
        Console.WriteLine(x==x2);
    }

    internal static void Do()
    {
        var a  = new A();
        var a2 = new A();
        var b  = new B();
        var b2 = new B();
        CheckChosenOper(a,a2);      // 1. "False"
        CheckChosenOper(b,b2);      // 2. "False" !?
        CheckChosenOper<A>(a,a2);   // 3. "False"
        CheckChosenOper<A>(b, b2);  // 4. "False"
        //CheckChosenOper<B>(a, a2); //Complie Error
        CheckChosenOper<B>(b, b2);  // 5. "False" !?
        Console.WriteLine(a == a2); // 6. "False"
        Console.WriteLine(b == b2); // 7. "True"
        Console.WriteLine(a == b2); // 8. "False"
        Console.WriteLine(b == a2); // 9. "False"
    }
}

一些问题:

A) 为什么#2 & #5 打印“False”?B- 我希望在这些情况下应该从类中获取运算符实现。

B) 我是对的:由于 #8 和 #9 都打印“False” - Cosen 运算符实现是第一个发现的,两种事实参数类型都可以转换为它的参数类型?

c) 选择运算符 == 实现的常见规则是什么?

标签: c#.netgenericsoperator-keywordequality-operator

解决方案


A)好吧,您的方法是一个通用方法,即使您有意指定类型CheckChosenOper,它仍然“使用”类 A 作为基类并且它是自己的运算符。似乎运算符在派生类中没有被覆盖,并且方法只能使用它已知的东西:A类。它不能自行运行并使用反射来搜索其他有效的相等运算符。==<B>CheckChosenOper

B) 不,你错了。在 #8 和 #9 的情况下,编译器有两个选择 - 将 A 向上转换为 B 并将 B1 与 B2 进行比较,将 B 向下转换为 A 并将 A1 与 A2 进行比较。由于向上转换是一个禁忌并且必须通过转换运算符专门完成,因此编译器采用简单的 A1==A2 选择。

C) 好吧,如果我在写一个struct,我肯定会去写一个。以及!=, GetHashCode,IEquatable<>和其他一些东西。但是必须有充分的理由来创建自己的结构,因为它们的行为不同。


推荐阅读