2012-08-05 54 views
1

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

如果有人知道如何做到这一点?

感谢

+0

我不知道C#的泛型,但至少在C++中;你可以创建一个泛型函数,它假设一个类型的操作符已经被重载,如果te类型没有,那么编译时就会抛出一个异常。 – 2012-08-05 17:56:27

+0

我会遵循这种模式:http://stackoverflow.com/questions/63694/creating-a-math-library-using-generics-in-c-sharp – 2012-08-05 17:56:55

+0

@ RichardJ.RossIII:请注意,在C#中,你不能确保一个方法有运算符重载(它们是静态方法,我讨厌这种c#行为)。这就是说,如果一个对象是一个带有泛型子句的数字,你就不能真正“理解”它。 – 2012-08-05 17:58:24

回答

6

六个选项:基于T

  • 每种类型的过载的执行时间型

    • 使用反射你关心
    • 使用的if/else对于每一个类型的,你在乎
    • 创建包含Dictionary<Type, Func<object, object>>为每一个类型的委托你照顾.NET 4的约
    • 使用dynamic

      public T Foo<T>(T value) 
      { 
          dynamic d = value; 
          return Math.Abs(d); 
      } 
      
    • 使用像马克Gravell的的MiscUtil

    generic operators部分,我可能会去,如果可能的过载选项。它会在编译时适当地限制你,避免任何潜在的耗时的装箱/反射。

  • 4

    你不能用泛型做到这一点 - 没有泛型类型的限制,这将确保在传递类型是数字类型。

    2

    我认为这是不合逻辑的写一个通用的方法,本质上表现不同的东西。浮动和双精度工作方式类似,但int不以这种方式工作(它们没有小数部分)。

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

    1

    您可以通过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)); 
    }