4

byteや などの組み込み型で動作することを目的としたジェネリック クラスを作成したいと考えていますushort。内部計算では、ジェネリック型を整数にキャストし、ジェネリック型に戻す必要があります。そのようなコードをコンパイルする方法を見つけました。たとえば、次のようになります。

class Test<T> where T : struct, IConvertible
{
    public static T TestFunction(T x)
    {
        int n = Convert.ToInt32(x);
        T result = (T)Convert.ChangeType(n, typeof(T));
        return result;
    }
}

このような変換を使用すると、計算ループで使用するとパフォーマンスが大幅に低下する可能性があると思います。これらの変換を行うためのより良い方法はありますか?

4

2 に答える 2

1

少し考えた後、質問といくつかの回答のおかげで、私の古い問題であるジェネリック T での操作の使用が解決されたことをうれしく思います。

最初に Cast を使用した例 (OP の要求による)

public static class Cast<T, U>
{
    public static readonly Func<T, U> Do;

    static Cast()
    {
        var par1 = Expression.Parameter(typeof(T));

        Do = Expression.Lambda<Func<T, U>>(Expression.Convert(par1, typeof(U)), par1).Compile();
    }
}

そして、乗算の例:

public static class Multiply<T>
{
    public static readonly Func<T, T, T> Do;

    static Multiply()
    {
        var par1 = Expression.Parameter(typeof(T));
        var par2 = Expression.Parameter(typeof(T));

        Do = Expression.Lambda<Func<T, T, T>>(Expression.Multiply(par1, par2), par1, par2).Compile();
    }
}

使い方はとても簡単です:

int x = Conv<T, int>.Do(someTValue);

最後に、静的クラスが作成されます。この単一フィールドはDo、式ツリーで構築された操作を「指す」デリゲートであるという名前の読み取り専用静的プロパティです。

乗算も同様です。

T res = Multiply<T, T>.Do(someTValue1, someTValue2);

一般的な場合、乗算は直接乗算よりも 3 倍遅くなります (リリース モード、デバッグなし)。

掛け算から始めることで、明らかに他の操作を簡単に行うことができます

(興味深いことに、私はツリーについてよく知っていExpressionましたが、さまざまな型を格納するための "辞書" として静的クラスを使用することを考えたことはありませんでした。.NET にジェネリック クラスをDictionary<Type, Delegate>"処理" させる代わりに、常に次のようなことを行いました。Dictionary専門。)

于 2013-08-12T08:19:46.163 に答える