質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.09%

インターフェースに演算子をオーバーロードする方法

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 2,597

score 9

 前提・実現したいこと

C#でinterfaceに演算子のオーバーロードをしたい。

 発生している問題・エラーメッセージ

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

 該当のソースコード

interface ITest {
  public static double operator + (ITest A,ITest B);
}

 試したこと

実際にこのインターフェースを使用するクラスに演算子のオーバーロードを実装しようとしたが、設計上無理があったため、断念。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • Zuishin

    2018/08/15 14:43

    何が聞きたいのでしょう?

    キャンセル

  • Iwancof

    2018/08/15 14:47

    インターフェースに演算子をオーバーロードして、そのインターフェースを含むインスタンスすべてにその演算ができるようにしたいです。あまり触っていない言語なので、不備があったらすみません。

    キャンセル

  • Zuishin

    2018/08/15 14:50

    演算子のオーバーロードには実装が必要なのでインターフェースではできません。断念したのではないのですか?

    キャンセル

  • Iwancof

    2018/08/15 14:57

    日本が苦手ですみません。断念したのは「このインターフェースを使うクラスに演算子をオーバーロードをすること」です。僕がやりたいのは、このインターフェースを持つすべての演算子に"+"の演算ができることを保証したいのですが、それがインターフェースにできないということは保証できないということですか?

    キャンセル

回答 2

+3

何でできなんだ…と疑問に思ったのでちょっと調べてみました。

演算子を再定義出来る言語は意外と少ないです。C++、C#、Scala、Kotlin、Python、Ruby、Perl6、Haskell、Swift、Rust、あれ、以外とあるっぽい。ただ、これらの言語を大きく分けると、演算子が関数としてオーバーロードしている言語と、演算子がただのインスタンスメソッドにすぎない言語に大別されます。

a + bという表現を解釈するとき、+(a, b)となるかa.+(b)となるかはかなりの違いがあります。C++はその柔軟性を生かすために、両方の解釈が出来るようにしました。これが混乱の元です。オブジェクト指向としてはa.+(b)とインスタンスメソッドとして解釈する方が正しく思えます。しかし、+(a, b)と解釈できる仕様は、オープンクラスではないC++のような言語において、既存の型を前置、ユーザー定義型を後置に取る演算子の動作を追加するために必要です。この+(a, b)解釈が出来ない言語では、例えばScalaは暗黙の型変換という仕組み、Rubyはcoerceというメソッドを介するという仕組み、といった別手段を用いないといけません。そう、a.+(b)という解釈だけでは無理が生じるので、C++では+(a, b)の両方が出来るようになったのです。

C#はC++からの簡素化を目指しました。演算子オーバーロードについても簡素化し、C++のような二つも書き方があるようなものは避けたかったのです。で、どうしたかというと、+(a, b)を取りました。この書き方は、インスタンスメソッドではありませんのでインスタンスに紐付けらる物ではありません。つまり、C++のように関数として書くか、C#のようにクラスメソッド(staticメソッド)として書く必要があると言うことです。

後は簡単です。インターフェースはインスタンスの動きの枠組みを決めるためのものであって、クラスそのものの枠組みを決めるための物ではありません。だからstaticメソッドは対象外になる、ただそれだけです。

なお、単なるメソッドであるScalaやRubyでは演算子の再定義は(必要であれば)積極的に使われているようにみえます。これらの言語は、書き方の違いだけで、他のメソッドと違いは無いからだと思います。


【おまけ】
Stack Overflowに何が何でも強制させたいという手法が載っていました。ただし、抽象クラスに限ります。
interface - Is there any way in C# to enforce operator overloading in derived classes? - Stack Overflow

public abstract class MyClass
{
    public static MyClass operator +(MyClass c1, MyClass c2) 
    {
        return c1.__DoAddition(c2);
    }

    protected abstract MyClass __DoAddition(MyClass c2);
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/08/16 06:27 編集

    目的とは違いますが、ためになる回答なので高評価しました。

    キャンセル

checkベストアンサー

0

演算子のオーバーロードは、優秀なフレームワーク、ライブラリ製作者以外は必要のない機能のなので、
考えるだけ無駄だと思います。

普通に、.Add() でやったほうがいいと思います。

そもそも、複数のインタフェースがあったとき、それぞれのインタフェースで演算子をオーバーロードしたら、何が起こるかわからないものになると思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.09%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る