我想创建一个执行基本数学运算的通用方法。例如。如果将double传递给函数,它将返回double。
public static T Multiply<T> (T A, int B)
{
//some calculation here
return (T) A * B;
}
这对我不起作用。
编辑:我得到一个错误运算符'*'不能应用于'T'和'int'类型的操作数
但是我想知道是否还有其他方法可以实现我想要的目标?
谢谢
您可以通过为特定类型构造和编译 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);
}
为了避免每次使用表达式时都重新编译它,可以将它缓存在字典中。
请注意,这种方法有一定的局限性:
T
by ,T
T
没有转换。这不适用于小于 的类型int
,int
.这些都没有在编译时检查。
这是最简单的实现,但效率不高:
public static T Multiply<T>(T A, int B)
{
T val = default(T);
try
{
val = (dynamic)A * B;
}
catch
{ }
return val;
}
根据您的需要,它可能适合您。您可以考虑不在方法中处理异常,或者使用一个out
值,以便您可以返回答案和成功值。
被困在较旧的 .Net 版本上,无法访问动态,我有一个非常简单的类,它可以完成您正在寻找的工作,并允许使用实际的运算符:Numeric它可能值得一看 current 。网也。
方法声明:
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 类。显然,它还具有通常更具可读性的算法实现的好处,并且可以支持实现运算符的自定义类。
这是我使用泛型与数字进行比较的示例:
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;
}