Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何正确设计使用显式接口继承和运算符重载的类_C#_.net_Interface_Architecture_Operator Overloading - Fatal编程技术网

C# 如何正确设计使用显式接口继承和运算符重载的类

C# 如何正确设计使用显式接口继承和运算符重载的类,c#,.net,interface,architecture,operator-overloading,C#,.net,Interface,Architecture,Operator Overloading,我喜欢总是使用显式接口继承和私有构造函数定义类,这样我就可以强制客户机使用接口,而不是直接更新类。我以前从未发现需要使用操作符重载,但现在我有了一个非常适合的类。不幸的是,我发现您必须使用静态方法来重载运算符,这意味着您不能在接口上定义它们 为什么我不喜欢这个 每次需要使用运算符时都必须强制转换和对象:(IMyObject)object1++ 无法将接口传递给重载函数: public static bool operator ==(IMyObject a, IMyObject b) {

我喜欢总是使用显式接口继承和私有构造函数定义类,这样我就可以强制客户机使用接口,而不是直接更新类。我以前从未发现需要使用操作符重载,但现在我有了一个非常适合的类。不幸的是,我发现您必须使用静态方法来重载运算符,这意味着您不能在接口上定义它们

为什么我不喜欢这个

  • 每次需要使用运算符时都必须强制转换和对象:
    (IMyObject)object1++
  • 无法将接口传递给重载函数:

    public static bool operator ==(IMyObject a, IMyObject b)
    {
        return a.Equals(b);
    }
    
    不起作用

    您必须使用实现来定义它:

    public static bool operator ==(MyObject a, MyObject b)
    {
        return a.Equals(b);
    }
    
  • 我遇到的第一个缺陷是
    Equals()
    不起作用
    Equals()
    只调用使用显式接口继承定义的GetHashCode(),该接口继承调用的是
    System.Object.GetHashCode()
    ,而不是我通过显式接口继承定义的:

     int IMyObject.GetHashCode()
     {
         return _value.GetHashCode();
     }
    
    我可以在对象上重写GetHashCode并调用
    (IMyObject)this.\u value.GetHashCode()但这看起来真的很混乱

    我知道您可以使用抽象类而不是接口,并在抽象类中的运算符上声明重载。老实说,我不知道我是否喜欢这个,但也许这是最好的方式?我不想让客户机在我的类上使用不同的功能,我也不想让任何人像我一样遇到缺陷

    糟糕的是,语言团队没有设计操作符重载,以便您可以使用虚拟方法,但我相信他们有自己的理由

    编辑:

    我决定违背我在这里的最佳实践,让客户机直接创建类,而不是使用接口。我宁愿不停地使用类的不同功能。我将把这个问题留在这里,以防将来有人能想出一个好的解决方案。

    接口平等imho模棱两可。例如:
    Cat
    Dog
    执行
    IAnimal
    。猫
    和狗
    相等吗?我不得不恭敬地表示不同意。是的,在您的示例中,这没有意义,但是假设您有IPerson,并且您有以下实现它的类:经理、执行官、员工和顾问。你有一个IPerson的收藏。您想知道每个IPerson的类型,以便可以强制转换它并使用“==”吗?您可以说使用SSN来查看它们是否相等。虽然我需要实现比“==”更多的运算符,比如“+=1”、““++”、“--”等,但我仍然支持我的类。。。客户会经常使用的。很多时候,您只是将实现/接口分离,所以实现接口的安装始终是同一类。好吧,问题仍然是一样的:经理和主管是一样的,还是员工和顾问是一样的?在一种情况下,它们可能是相同的,而在另一种情况下,它们不是相同的。这就是为什么oop不支持接口级别的平等性。事实上,在大多数linq操作中,它们接受
    IComparer
    IEqualityComparer
    来处理这种情况,而不是使用hashcodes.interface equality imho是不明确的。例如:
    Cat
    Dog
    执行
    IAnimal
    。猫和狗相等吗?我不得不恭敬地表示不同意。是的,在您的示例中,这没有意义,但是假设您有IPerson,并且您有以下实现它的类:经理、执行官、员工和顾问。你有一个IPerson的收藏。您想知道每个IPerson的类型,以便可以强制转换它并使用“==”吗?您可以说使用SSN来查看它们是否相等。虽然我需要实现比“==”更多的运算符,比如“+=1”、““++”、“--”等,但我仍然支持我的类。。。客户会经常使用的。很多时候,您只是将实现/接口分离,所以实现接口的安装始终是同一类。好吧,问题仍然是一样的:经理和主管是一样的,还是员工和顾问是一样的?在一种情况下,它们可能是相同的,而在另一种情况下,它们不是相同的。这就是为什么oop不支持接口级别的平等性。事实上,在大多数linq操作中,它们接受
    IComparer
    IEqualityComparer
    来处理这种情况,而不是使用hashcode。