2012-03-06 108 views
3

假設我想編寫一個通用的Max方法,該方法返回兩個值的最大值。我可以利用通用接口IComparable<T>:[忽略null檢查]通用約束語法和用法

static T Max<T>(T x, T z) where T : IComparable<T> 
{ 
    return x.CompareTo(z) > 0 ? x : z; 
} 

細。現在我不明白的第一件事就是以下擴展上面的例子:

static void Initialize<T>(T[] array) where T : new() 
{ 
    for (int i = 0; i < array.length; i++) 
     array[i] = new(T); 
} 

它會在哪裏neccessary採用這種語法(new()在這種情況下,這裏混淆我)?此外,我已經看到了befuddles我更進一步以下通用模板

class GenericClass<T> where T : SomeClass, Interface 
             where U : new() 
{ /* Some Code */ } 

在這裏,我認爲T是一種約束是從類型約束U過濾。所以,如果是這樣的話,那麼我們可以寫

class Magic<T> 
{ 
    Magic<U> SomeOtherClass<U>() where U : T { /* Some Code */ } 
} 

做我有這個權利,是多少級這種層次的可能是在C#中?

回答

4

那麼,你已經給出了new()約束有用的例子:如果你想用「new」對象填充數組,每個對象都是通過調用無參數構造函數創建的。

至於這樣的:

class GenericClass<T> where T : SomeClass, Interface 
            where U : new() 

...這將無法編譯,因爲它試圖約束U,但是這不聲明爲一個類型參數。

但是你的Magic<T>會編譯,並會強制UT適當兼容。 (該確切細節是非常複雜的,請參閱該規範。)

例如,你可以調用

new Magic<Stream>.SomeOtherClass<FileStream>() 

new Magic<IFormattable>.SomeOtherClass<int>() 
+0

你叫我去規範來明天:]。這在這裏可能看起來像一個愚蠢的問題,但我想你可以有'Class SuperMagic {SuperMagic Magic(0)}其中U:T {...}我認爲這可以永遠持續下去嗎? 'T'和'U'是唯一可以表示泛型的字母嗎?再次感謝您的時間喬恩。祝一切順利。 – MoonKnight 2012-03-06 23:18:45

+0

@Killercam:說實話,你不太清楚你的例子是什麼意思。你應該試試看。不,這裏的標識符「U」和「T」是任意的。他們只是名字。如果您真的想要,可以將它們用於類型,並且可以使用任何其他名稱作爲類型參數。儘管這個約定是以'T'開始的。 – 2012-03-06 23:21:07

+0

@Killercam,這裏是獲取C#語言規範的鏈接 - http://msdn.microsoft.com/en-us/library/ms228593(v=vs.100).aspx,特別是第4.4.4節介紹了約束。 – 2012-03-06 23:32:44