none
关于泛型的问题 RRS feed

  • 问题

  • 我想写一个用辗转相除法计算最大公约数的函数,因为该法对于所有整型变量(如byte,sbyte,short,ushort,int,uint,long,ulong)都通用,于是我想到了利用泛型方法来实现,
    我的想法如下: public static T GCD<T>(T a,T b) where T:struct { ... }
    但上机一试发现编译错误,原因是代码中使用了a/b,a%b等运算,仅将T约束为struct并不能保证T类型一定能实现加减乘除等运算.
    我也不想把这个函数对每个整数类型都重载一次,还是想用泛型之类的方法,有没有什么办法可以解决上述问题?
    能不能把T仅约束为某几个特定的值类型?
    2009年11月26日 9:17

答案

  • 有点蹩脚的实现方法:)
    public interface IOperator<T>
    {
          T Add(T opA, T opB);
    }

    public IntOperator : IOperator<int>
    {
         int Add(int opA, int opB)
        {
            return opA + opB;
        }

    }

    public class GenericOperator
    {
         public static T GCD<T>(T a, T b)
              where T : struct
         {
              IOperator<T> genericOp = null;
              if (typeof(T) == typeof(Int32)
              {
                   genericOp = (new IntOperator()) as IOperator<int>;
                   return genericOp.Add(a, b);
              }
             throw new ArgumentException("argument does not support this operation!");
         }
    }


    int a = GenericOperator.GCD<int>(1, 2);

    • 已标记为答案 ygc 2009年11月26日 13:47
    2009年11月26日 10:34

全部回复

  • struct 专有泛型的 Nullable<T>  简写T?
    你那样定义不支持的



    努力学习wpf
    2009年11月26日 9:23
  • 你好!
         我认为这个要求用泛型很难实现,因为你无法对类型参数做出假设,也无法对类型参数进行合适的约束,所以也就没有办法对他们进行计算!
         还是用重载来实现比较合适!实际上.NET Framework提供的类也都是使用重载来实现类似需求的,而不是用泛型
    周雪峰
    2009年11月26日 10:21
    版主
  • 有点蹩脚的实现方法:)
    public interface IOperator<T>
    {
          T Add(T opA, T opB);
    }

    public IntOperator : IOperator<int>
    {
         int Add(int opA, int opB)
        {
            return opA + opB;
        }

    }

    public class GenericOperator
    {
         public static T GCD<T>(T a, T b)
              where T : struct
         {
              IOperator<T> genericOp = null;
              if (typeof(T) == typeof(Int32)
              {
                   genericOp = (new IntOperator()) as IOperator<int>;
                   return genericOp.Add(a, b);
              }
             throw new ArgumentException("argument does not support this operation!");
         }
    }


    int a = GenericOperator.GCD<int>(1, 2);

    • 已标记为答案 ygc 2009年11月26日 13:47
    2009年11月26日 10:34
  • 虽然蹩脚,但很实用。谢谢。
    2009年11月27日 13:30