2012-01-20 15 views
4

可能重複:
What does this C# syntax mean?使用 '其中' 在C#

可能有人請澄清我在C#以下類聲明的區別:

public class SomeClass<T> where T : ISomeInterface 

public class SomeClass<ISomeInterface> 
+3

的可能重複[這是什麼C#語法是什麼意思?(http://stackoverflow.com/questions/2739859/what-does-this-c-sharp-syntax-mean),[C#,其中的關鍵字](http://stackoverflow.com/questions/2774041/c-sharp-where-keyword) –

+0

@CodyGray你投票結束了你的評論中的第二個鏈接。您必須在'Where'子句或泛型類型約束中擁有既得利益。 –

+0

@Chase:我只是做了,是的,因爲它是我發現的其他問題的重複。我有減少冗餘和重複的既得利益。它使您更容易找到您正在尋找的答案。 –

回答

8

第一個約束該類中的T是一個派生自或實現給定接口的類型。

如果你有

class Foo : ISomeInterface { } 
class Bar : ISomeInterface { } 
class Baz { } 

有了您的第一個定義,那麼您需要能夠建立一個通用的實例與前兩種類型,而不是第三。

public class SomeClass<T> where T : ISomeInterface // your definition 

var obj1 = new SomeClass<Foo>(); 
var obj2 = new SomeClass<Bar>(); 
var obj3 = new SomeClass<Baz>(); // not legal, Baz does not implement ISomeInterface 

第二,你所做的一切都是設法聲明一個類型參數,它恰好與接口名稱相同。它不是一個通用的類定義,只能用於接口,它不受接口的限制,它只是一個令人困惑的名字。以上所有三個類都可以用作類型參數。

public class SomeClass<ISomeInterface> // your definition 

var obj1 = new SomeClass<Foo>(); 
var obj2 = new SomeClass<Bar>(); 
var obj3 = new SomeClass<Baz>(); // legal, there is no constraint 

編輯:從下面的評論

我已經測試了 「var obj3 = new SomeClass<Baz>();」 和它的作品,但我不明白爲什麼。我想我不明白這個說法「第二,你所做的一切都是設法聲明一個類型參數,它恰好與接口名稱相同。」

在聲明泛型類的定義public class Blah<T>,該T佔位符。它是稍後填寫的類型參數。在您的第二個版本中,public class SomeClass<ISomeInterface>,ISomeInterface是佔位符的名稱!它不是的接口,它不限制類使用ISomeInterface,它只是使用與該類型參數名稱相同的名稱。 類型參數可能是任何東西。這是填充佔位符的參數var foo = new SomeClass<string>()。這裏,通用參數已填入string

您做什麼我都做得比較早,只需創建一個實例

var instance = new SomeClass<string>(); 

或者,您可以使用通用的基本類型爲另一種類型填充它在填充的說法。

class AppleSomeClass : SomeClass<Apple> 

的一點是,這是慣例,單一類型的參數情況下,使用T,但它僅公約。 T可以改爲命名任何東西。美國蘋果。你已經發現你也可以將它命名爲與現有類型相同的東西,但不幸的是,這會導致你的困惑。


原來的答覆繼續

有了約束,你可以限制一個類或泛型方法的類型參數有一定的屬性給它。例如,您可以將其限制爲引用類型或值類型。

where T : class // reference type 
where T : struct // value type 

您可以指定它必須從類派生或實現一個接口

where T : Foo // derives from Foo 
where T : IFoo // implements IFoo 

而且你可以要求它有一個參數的構造函數

where T : new() 

你可以匹配這些,按上面列出的順序。類或結構約束必須是第一個,然後是基類型或接口,最後是構造函數。

where T : class, IFoo 
where T : class, new() 
where T : class, Foo, new() 
+0

感謝您的詳細解釋。我測試了「var obj3 = new SomeClass ();」它的工作原理,但我不明白爲什麼。我想我不明白這個說法「第二,你所做的一切都是設法聲明一個類型參數,它恰好與接口名稱相同。」 – Sandy

+0

@Sandy,看到擴展的答案。 –

+0

明白了。非常感謝你安東尼。 – Sandy