我想编写泛型类,用于处理内置类型,如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;
}
}
我认为使用此类转换可能会显着降低性能,如果它们用于计算循环中。有没有更好的方法来进行这些转换?
答案 0 :(得分:2)
int
到T
转换有点棘手。我想你可以在这里使用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
。)