2013-01-15 21 views
5

で演算子オーバーロードを必要とするカント、あなたがこのようなコード記述することができます。なぜあなたはC++でジェネリック

template<class T> 
T Add(T lhs, T rhs) 
{ 
    return lhs + rhs; 
} 

をしかし、あなたはC#で、このような何かを行うことはできません。

public static T Add<T>(T x, T y) where T : operator+ 
{ 
    return x + y; 
} 

があります何らかの理由がありますか?私はそれが反射を介して達成することができることを知っています(オブジェクトで汎用Addを実行してから、すべてのタイプを調べて実行します)。しかし、これは非効率的で、スケールがよくありません。だから、もう一度、なぜ?

+0

これは、http://stackoverflow.com/questions/756954/arithmetic-operator-overloading-for-a-generic-class-in-c-sharpの複製のように見えます。 – neontapir

+0

@neontapir受け入れられた答えは、反映を使用しています。私はそれがそうすることができ、私はしたくないと知っていると言いました。 –

+0

2番目の段落では、C#でこれを行うことはできないと思います。つまり、質問に「演算子のオーバーロードタイプの制約はないのですか? (私が知らない答え、btw)。 –

答えて

5

これは存在しない固有の理由はありません。ジェネリック型の制約が実装される方法は、インタフェース呼び出しを介して行われます。 operator+を提供するインターフェイスがあれば、これはうまくいくでしょう。

このインターフェイスは、すべて関連タイプは、C++テンプレートベースのアナログと同じように一般的である必要があります。

もう1つの問題は、.NETに複数のディスパッチがないことです。インターフェイスコールは非対称である:a.Plus(b)b.Plus(a)とは異なるものを意味する可能性があります。 Equalsには同じ問題がありますが、btwです。

この問題は、「有用性」バーまたは「コスト/ユーティリティ」バーに適合していない可能性があります。これは不可能ではなく、実用的な問題です。

証明書:((dynamic)a) + ((dynamic)b)です。

+3

あなたが言及していないこと(少なくとも明示的ではない):オペレータは 'static'メソッドでなければならず、 'static'メソッドはメンバにはなれないので、' operator + 'を提供するインタフェースは*できません。インタフェース。 – svick

+1

@svick私は、.NETの将来のバージョンについて言及しています。演算子は、インスタンスメソッドのバージョンで補完することができます。今、あなたは正しい。 – usr

3

CLRはこのような制約をネイティブにサポートしていないため、C#設計チームは明らかにCLRと同じ一連の制約をサポートすることにしました。おそらく、CLRチームとC#チームの両方は、このような機能を実装することのメリットは、その仕様の実装、実装、およびテストのコストを上回るものではないと考えていました。

このような制約をサポートする.NET言語を使用する場合は、F#を検討してください。

+0

私はF#が(CLR制約の限界のために)特定の場合にのみ、そのような制約をサポートしていると信じていますが。 – svick

+1

@svick - F#は可能な限りCLR制約を使用しますが、CLRタイプのシステムでは表現できないF#固有情報の多くを表す独自のメタデータ形式を持っています。そのようなアイテムの1つはメンバ制約であり、特定の名前とシグネチャを持つメソッドを持つ型が必要です。 – kvb

0

演算子の制約を実装するにはいくつかの方法があり、それらはすべて自明ではない(おそらくCLRを変更する必要があります)か、または重大な欠点があります(たとえば、2つの整数)。

これは、比較的遅く、一般的で安全でない方法(dynamicを使用する方法、または種類が限定された高速で、過大な過負荷を持つ方法)のいずれかです。そのため、そのような機能はおそらく「持っているのがいい」と考えられますが、そのような変更を保証するのに十分なほど重要ではありません。

関連する問題