2010-02-03 29 views
7

一位同事指出我在C#中一個奇怪的例子(不太確定這是否真的很奇怪)。
假設你有一個Employee類。如果你想創建Employee類型的泛型列表<>,你可以簡單地做:
爲什麼在C#泛型中這是不可能的?

List<Employee> x = new List<Employee>; 

我明白,我需要的員工類型傳遞到泛型列表,以便它知道所需要的類型信息Employee並生成返回並接受與Employee兼容的參數的方法。

現在我的問題是,爲什麼不可能做到以下幾點?

Employee x = new Employee(); 
List<typeof(x)> list = new List<typeof(x)>(); 

不應該這樣足夠了名單<所需的信息>瞭解,爲了創建一個列表?換句話說,作爲Employee類型的x的類型現在作爲一個泛型類型參數傳遞給列表<>,它(與我以前相信的一樣)與傳遞列表類型名稱相同(在本例中爲Employee) 。

我知道類似這樣的東西在Java中使用(使用.class)關鍵字在變量上。

我敢肯定,我錯過了一些東西,所以請,讓我這些傢伙!

回答

30

不,相當於不是在Java中可用。您不能使用「x.class」來獲取變量的聲明類型。

此外,typeof(x)不會在C#工作,要麼得到一個變量的類型 - 它返回類型名稱,例如Type參考typeof(string)將返回對與System.String類型關聯的對象Type的引用。這相當於在Java中使用String.class。 (請注意,同樣的,這將.class的類型名稱,一個變量名。)

Java泛型不支持喜歡你的最後陳述或者任何東西。如果您認爲他們這樣做,請給一個樣本:)

可以在C#中做的是使用類型推斷做你想做什麼:

public static List<T> CreateListForSampleType<T>(T sample) 
{ 
    return new List<T>(); 
} 

... 

Employee x = new Employee(); 
var list = CreateListForSampleType(x); 

需要注意的是,我們沒有理由爲什麼C#couldn 't可以擴展爲允許類似於typeof(variablename)List<typeof(variablename)>之類的東西 - 畢竟這是所有編譯時類型信息。然而,我看不出它會滿足團隊對實用性的要求......還有其他更有用的功能,我希望先看到:)

+1

好的代碼示例。如果你在'list'變量上使用'typeof',會發生什麼? – FrustratedWithFormsDesigner 2010-02-03 15:09:41

+1

typeof(list)會導致編譯錯誤。 – 2010-02-03 15:21:26

+0

喬恩,謝謝你的詳細解答!由於這是編譯時間信息,所以我正處在正確的軌道上。說到它是否有用,雖然有些爭議;)。 – Galilyou 2010-02-03 15:36:27

2

原因是typeof()返回一個類型的對象,而你需要一個類型名來在編譯時初始化一個列表。

1

typeof與類名一起使用。在對象上使用GetType(),但僅在運行時...

2

答案的一部分是x的類型在編譯時不可用,即它可能會使用這樣的創建:

Employee x = EmployeeFactory.NewEmployee("John Doe"); // Returns TraineeEmployee, Employee or ManagementEmployee; 

List<typeof(x)> l = new List<typeof(x)> l(); // What type is it? 

但是,您可以創建一個基類的你想在清單上存儲(或者甚至是的「對象」的名單)什麼的清單。

1

缺少的東西 - imho - 是編譯時的靜態類型引用和運行時的dinamyc類型引用(通過System.Type的實例)之間的區別。

typeof()和.GetType()給你後者。 (分別用於類型和實例)

我希望它清楚。

Jon Skeet上面的代碼很酷。

0

自C#3.0以來,無法找到創建空列表的原因。

我通常創建列表實例僅與從IEnumerable)一個ToList方法,它是依次使用產率返回,CONCAT()生成的,重複(),其中(等

var list = CreateEmployees().ToList(); 

public IEnumerable<Employee> CreateEmployees() 
{ 
yield return new Employee("Foo"); 
yield return new Employee("Bar"); 
} 
相關問題