2016-03-22 42 views
1

在C++中我經常使用這個模板函數...C#泛型函數isPowerOf2 <T>(T X)的實施

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'

如果我刪除了通用的東西&只是讓「public static bool isPowerOf2(int x)」,它工作正常(就像在various implementations here),但我想的實施是通用的,所以它會在任何整數類型的工作。

+0

我不是一個C#專家,但我認爲答案是否定的,你不能這樣做。 http://stackoverflow.com/q/32664/3973077 –

+0

「任何整數類型」你是指任何數字,如雙或十進制?您必須將'T'限制爲僅數字(而不是字符串),但我認爲這不能在C#中完成。 –

回答

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); 
} 
2

C#做靜態類型檢查,這可以聲明dynamic型旁通。輸入參數類型爲dynamic時,仍然可以執行想要的操作。請注意0​​只適用於整數,浮動和雙倍失敗。

public class Utils 
{ 
    // ... 

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

入住這example

+0

動態可以接受字面上的任何東西。 COM對象或甚至爲空。 – Saleem

+0

這是正確的,應該爲這種情況添加防禦性編碼。 –