将泛型参数转换为整数和从整数转换

时间:2013-08-12 08:16:43

标签: c# generics casting

我想编写泛型类,用于处理内置类型,如byteushort。在内部计算中,我需要将泛型类型转换为整数并返回泛型类型。我找到了编译此类代码的方法,例如:

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;
    }
}

我认为使用此类转换可能会显着降低性能,如果它们用于计算循环中。有没有更好的方法来进行这些转换?

2 个答案:

答案 0 :(得分:2)

intT转换有点棘手。我想你可以在这里使用Expression课程。

Test<T>类应该看起来像这样:

class Test<T> where T : struct, IConvertible
{
    private static Func<int, T> _getInt;

    static Test()
    {
        var param = Expression.Parameter(typeof(int), "x");
        UnaryExpression body = Expression.Convert(param, typeof(T));
        _getInt = Expression.Lambda<Func<int, T>>(body, param).Compile();
    }

    public static T TestFunction(T x)
    {
        int n = Convert.ToInt32(x);
        T result = _getInt(n);
        return result;
    }
}

它会在静态构造函数中为您准备_getInt = x => (T)x并稍后使用它,将int转换为T

答案 1 :(得分: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);

在一般情况下,乘法比直接乘法慢一些(在发布模式下,没有调试)。

从乘法

开始,显然可以轻松完成其他操作

(有趣的是我对Expression树很了解,但我从未想过使用静态类作为“字典”来包含各种类型。我总是做类似Dictionary<Type, Delegate>的事情。而不是让.NET通过泛型类专门化“处理”Dictionary。)