2009-05-27 10 views
4

これを行う方法はありますか?基本的な数学演算子を実装するために汎用パラメータを制約するにはどうすればよいですか?

T型の加算、減算を行うことができるTのコレクションクラスが必要です。私は同じコードを持つ複数のコレクションを持つ代わりにT genericを保ちたいと思います。

ジェネリックTをどのように制約しますか?

例:コレクション(TのIDoMaths)を定義したいと思います。私はそれが遅くなると思うので、操作を行うために名前付きのメソッドで私自身の整数などのクラスを作成したくないです。コードのこの部分は実際に頻繁に呼び出され、パフォーマンスのボトルネックになりがちです。

答えて

7

残念ながら、あなたはできません。

implementedMiscUtilmore general articleもあります)の一部として、Marc Gravellが回避策があります。これはきちんとしていますが、静的型チェックを失います。

(型チェックを失うという点で)同じような文脈ではC#4.0の新dynamic機能を使用すると、実行時にのみ、それらを解決し、任意の方法で演算子を使用することができます:

dynamic x = 10.0; 
dynamic y = 3.0; 
double z = x/y; // z = 3.3333333 (double arithmetic) 

dynamic a = 10; 
dynamic b = 3; 
int c = a/b; // c = 3 (integer arithmetic) 

ただ、この日の午後、私はこれを使用してEnumerable.Sumの動的フォームを実装しました。私はそれをベンチマークしようとしています。最近、Marc Gravellもblog postを書きました。

VBを使用している場合、遅延バインディングのコードセクションでOption Strictをオフにしても同じ効果が得られる可能性がありますが、VBについてはC#恐れている。

+0

これは、現在のジェネリックの実装での残念な制限です。 Marcの実装は、問題を扱う際にも私が見てきた最高のものです。 connect.microsoft.comには、これに関するいくつかのサポート記事があります。それらはここで見つけることができます:http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?Feedback=94264ここ:http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID= 325177およびhttp://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=338861を参照してください。 – LBushkin

+0

intを使用して動的を使用するつもりはありませんか? –

+0

Doh - ありがとう、固定:) –

4

もっと単純ですが、少し冗長性のある代替ソリューションが必要な場合は、ちょっと立ち上がってみてください。ここでの利点は、それが完全にtypesafeだということです。

ここでは、intとfloatの+と - の演算を実装するクイックダーティバージョンがあります。それを拡張してより多くの操作を含めるとともに、より多くのプリミティブ型(二重、十進数など)をサポートするか、それともカスタム型さえサポートすることは自明であるべきです。 GenericMathを必要なものに置き換えてください。

class Program 
{ 
    static void Main(string[] args) 
    { 
     var gsInt = new GenericMath<int,IntOperators>(); 
     var gsFloat = new GenericMath<float,FloatOperators>(); 

     var intX = gsInt.Sum(2, 3); 
     var floatX = gsFloat.Sum(2.4f, 3.11f); 
    } 
} 

interface IOperators<T> 
{ 
    T Sum(T a, T b); 
    T Difference(T a, T b); 
} 

sealed class IntOperators : IOperators<int> 
{ 
    public int Sum(int a, int b) { return a + b; } 
    public int Difference(int a, int b) { return a - b; } 
} 

sealed class FloatOperators : IOperators<float> 
{ 
    public float Sum(float a, float b) { return a + b; } 
    public float Difference(float a, float b) { return a + b; } 
} 

class GenericMath<T,Y> 
    where Y : IOperators<T>, new() 
{ 
    private readonly static Y Ops = new Y(); 

    public T Sum(T a, T b) 
    { 
     return Ops.Sum(a, b); 
    } 

    public T Difference(T a, T b) 
    { 
     return Ops.Difference(a, b); 
    } 
} 
+0

フル開示 - 一般的な数学演算を実行するクラスのインスタンスにIOperators実装タイプを提供する必要があります。 – LBushkin

+0

+1、短い甘いとうまく動作します – smirkingman

関連する問題