web-dev-qa-db-ja.com

C#インターフェイスに演算子を含めることはできません

C#インターフェイスに演算子を含めることが許可されていない理由を誰かが説明できますか?

ありがとう。

40
Jake

C# 演算子は静的である必要があります 。定義上、インターフェースはインスタンスに適用されます。静的メンバーを実装するために型を要求するメカニズムはありません。

編集:
C#8.0以降、ご覧のとおり ここ 、インターフェイスでローカルメソッドを定義し、インターフェイス自体に実装できるようになりました。実装する必要のあるオーバーロードに追加のパラメーターを提供するだけの場合に、実装がそれらのオーバーロードにも注意を払う必要なく、メソッドオーバーロードを作成できるようにします。
これに加えて、インターフェース内で演算子を定義することもできますが、演算子は静的である必要があるため、インターフェースに実装する必要があります。

したがって、C#8.0では、「C#8で機能します」の後に「1」が表示されます。

interface ICanAdd
{
    int Value { get; }

    public static int operator+ (ICanAdd lvalue, int rvalue)
    {
        Console.WriteLine("this works in C# 8");
        return lvalue.Value + rvalue;
    }
}

class Add : ICanAdd
{
    public int Value => 0;
}

class Program
{
    static void Main(string[] args)
    {
        ICanAdd foo = new Add();
        var x = foo + 1;
        Console.WriteLine(x);
    }
}

2020-01-23を編集

変換、等式、または不等式の演算子をインターフェイスに追加することはできません。追加しないと、次のエラーが発生します。

CS0567 C#インターフェイスには、変換、等式、または不等式の演算子を含めることはできません

60
dkackman

クラスは複数のインターフェースを実装できるため、インターフェースに演算子を定義することはできません。このコードが可能であると想像してください:

static class Fooness {
  public static operator==(IFoo l, IFoo r) { ... }
}
static class Barness {
  public static operator==(IBar l, IBar r) { ... }
}

public class Foobar : IFoo, IBar { ... }

Foobarのインスタンスで使用する場合、どの==実装が優先されるべきですか? (そして、答える前に、IFoo/Foonessが1つのDLLであり、IBar/Barnessが別のものである場合)を想像してください)。

あいまいさをなんとかして解決できたとしても、それが良い考えであるかどうかを自問する必要があります。上記がoperator ==でそれが深刻な悪い考えであることを示していると思います。インターフェイスごとの==演算子の作成者は、比較に関してオブジェクトの重要な側面は、インターフェイスに含まれるものだけであると想定しています。それが真実である場合もありますが、一般的には真実ではありません。

そのため、シールされたクラスでのみ演算子を使用するのが賢明です。そうして初めて、オペレーターがオブジェクトについて正しく動作するのに十分なことを確認できます。

0
Steve Benz