2

我想创建通用函数 Math.Abs​​() 但我不知道如何做到这一点。如果我创建一个数学类,我不能为 T 值创建方法 Abs,因为我不知道 T 的类型。

如果有人知道该怎么做?

谢谢

4

4 回答 4

10

六个选项:

  • 根据执行时类型使用反射T
  • 为您关心的每种类型使用重载
  • 对您关心的每种类型使用 if/else
  • Dictionary<Type, Func<object, object>>为您关心的每种类型创建一个包含委托
  • dynamic在 .NET 4 中使用:

    public T Foo<T>(T value)
    {
        dynamic d = value;
        return Math.Abs(d);
    }
    
  • 使用类似 Marc Gravell 的MiscUtil的通用运算符部分的东西

如果可能的话,我可能会选择重载选项。它将在编译时适当地约束您,并避免任何可能耗时的装箱/反射。

于 2012-08-05T18:00:21.083 回答
4

你不能用泛型来做到这一点——没有泛型类型约束可以确保传入的类型是数字类型。

于 2012-08-05T17:55:25.793 回答
2

我认为为本质上表现不同的事物编写一个通用方法是不合逻辑的。Floats 和 doubles 以类似的方式工作,但 int 不以这种方式工作(它们没有小数部分)。

为每个方法编写一个重载应该是处理这个问题的正确方法,否则你最终会做一堆 if typeof 基本上是错误的。

于 2012-08-05T17:56:27.730 回答
2

您可以通过 T.GetType() 获取 T 类型。但它不会帮助你。您不能编写泛型方法,但可以为对象编写 Abs 方法:

private static object Abs(object num)
{
    var type = num.GetType();
    if (type == typeof(Int32))
    {
        return Math.Abs((int) num);
    }
    if (type == typeof(Int64))
        return Math.Abs((long)num);
    if (type == typeof(Int16))
        return Math.Abs((short)num);
    if (type == typeof(float))
        return Math.Abs((float)num);
    if (type == typeof(double))
        return Math.Abs((double)num);
    if (type == typeof(decimal))
        return Math.Abs((decimal)num);
    throw new ArgumentException(string.Format("Abs is not defined for type {0}", type.FullName));
}
于 2012-08-05T18:03:50.437 回答