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 版本上,无法访问动态,我有一个非常简单的类,它可以完成您正在寻找的工作,并允许使用实际的运算符: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 类。显然,它还具有通常更具可读性的算法实现的好处,并且可以支持实现运算符的自定义类。

于 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 回答