C#泛函函数实现isPowerOf2 <t>(T x)

时间:2016-03-22 02:19:19

标签: c# generics

在C ++中,我经常使用这个模板化函数......

template<typename T>
bool isPowerOf2 (T x) // returns nonzero if x is a power-of-2
{
  return x && ((x & (~x + 1)) == x);
}

...我试图在C#中实现相同的功能。所以,我能做到最好:

public class Utils
{
   // ...

   public static bool isPowerOf2<T>(T x) // returns true if x is a power-of-2
   {
      return (x != 0) && ((x & (~x + 1)) == x);
   }
}

但Visual Studio抱怨error CS0019: Operator '!=' cannot be applied to operands of type 'T' and 'int'error CS0023: Operator '~' cannot be applied to operand of type 'T'

如果我删除通用的东西&amp;只需使它成为&#34; public static bool isPowerOf2(int x)&#34;,它工作正常(就像在various implementations here中一样),但我希望实现是通用的,因此它适用于任何整数类型。

2 个答案:

答案 0 :(得分:5)

这很好地说明了为什么C#泛型不是C ++模板。 C#必须能够在不知道T的情况下编译代码,而C ++可以推迟编译直到知道T的类型。这让C ++可以弄清楚如何执行~+&等等。

使用C#的最简单方法是为计划与函数一起使用的类型进行多次重载。这导致少量的代码重复,但它比其他选项读得更好,例如使用LINQ表达式动态生成代码。

如果效果不重要,您还可以使用Convert.ToInt64

bool isPowerOf2 (object obj) {
    var x = Convert.ToInt64(obj);
    return x && ((x & (~x + 1)) == x);
}

答案 1 :(得分:2)

C#执行静态类型检查,可以绕过声明dynamic类型。如果输入参数类型为dynamic,您仍然可以执行您想要执行的操作。请注意~仅适用于整数,不适用于浮点数和双精度。

public class Utils
{
   // ...

   public static bool isPowerOf2(dynamic x) 
   {
      return (x != 0) && ((x & (~x + 1)) == x);
   }
}

选中此example