3

基本的な数学演算を実行する汎用メソッドを作成したいと思います。たとえば。関数にdoubleが渡されると、 double が返されます

public static T Multiply<T> (T A, int B)
{
   //some calculation here
   return (T) A * B; 
}

これは私にはうまくいきません。

編集: 演算子 '*' は型 'T' および 'int' のオペランドに適用できませんというエラーが表示されます

しかし、私がやろうとしていることを達成する他の方法があるかどうか疑問に思っていますか?

ありがとう

4

4 に答える 4

2

次のように、特定の型の LINQ 式を作成してコンパイルすることで、これを行うことができます。

private static IDictionary<Type,object> MultByType = new Dictionary<Type,object>();
public static T Multiply<T>(T a, int b) {
    Func<T,int,T> mult;
    object tmp;
    if (!MultByType.TryGetValue(typeof (T), out tmp)) {
        var lhs = Expression.Parameter(typeof(T));
        var rhs = Expression.Parameter(typeof(int));
        mult = (Func<T,int,T>) Expression.Lambda(
            Expression.Multiply(lhs, Expression.Convert(rhs, typeof(T)))
        ,   lhs
        ,   rhs
        ).Compile();
        MultByType.Add(typeof(T), mult);
    } else {
        mult = (Func<T,int,T>)tmp;
    }
    return mult(a, b);
}

式が使用されるたびに再コンパイルするのを避けるために、式を辞書にキャッシュすることができます。

このアプローチには一定の制限があることに注意してください。

  • Tbyの乗算Tが定義されていることが期待されます。
  • T乗算の出力は、変換なしであると予想されます。intこれは、より小さい型には当てはまりません。
  • タイプは からの変換をサポートする必要がありintます。

これはコンパイル時にチェックされません。

于 2013-09-18T14:59:38.563 に答える
2

これは実装が最も簡単ですが、効率的ではありません。

  public static T Multiply<T>(T A, int B)
  {
     T val = default(T);
     try
     {
        val = (dynamic)A * B;
     }
     catch
     { }

     return val;
  }

ニーズによっては、それで問題ない場合があります。メソッドで例外を処理しないか、out値を使用して、回答と成功値の両方を返すことができるようにすることを検討してください。

于 2013-09-18T15:13:43.273 に答える
0

ダイナミックにアクセスせずに古い.Netバージョンで立ち往生しているため、探していることを非常に多く実行し、実際の演算子を使用できる非常に単純なクラスがあります。ネットも。

メソッド宣言:

public static T LerpMinMax<T>(Numeric<T> input, Numeric<T> inputMin, Numeric<T> inputMax, Numeric<T> outputMin, Numeric<T> outputMax)
{
     if (input <= inputMin)
     {
        return outputMin;
     }
     else if (input >= inputMax)
     {
        return outputMax;
     }
     return outputMin + ((input - inputMin) / (inputMax - inputMin)) * (outputMax - outputMin);
}

そして、次を使用します。

float lerp = LerpMinMax<float>(0.55f, 0.0f, 0.1f, 0.0f, 1000.0f);

MiscUtil の Operator ほど柔軟ではありませんが、シンプルで (比較的) 高速であることを目的としています。操作を直接使用する場合 (たとえば、非ジェネリック型固有の実装を吐き出す T4 テンプレートを使用する場合など) よりもまだかなり遅いですが、上記の方法で使用すると、MiscUtil の Operator クラスと同等です。また、一般的により読みやすいアルゴリズムの実装という利点も明らかにあり、演算子を実装するカスタム クラスをサポートできます。

于 2014-08-20T10:36:22.297 に答える
-1

ジェネリックを使用して数値と比較する例を次に示します。

    public bool TIsEqual<T>(T f1, T f2, T margin)
    {
        T diff = default(T);
        T error = default(T);
        diff = Math.Abs((dynamic)f1 - f2);
        error = (dynamic)margin * f1;
        return (dynamic) diff < error;
    }
于 2013-11-21T20:11:07.163 に答える