2012-10-29 17 views
1

儘管在Google和SO上搜索,但似乎無法知道如何在.NET2.0中執行此操作。如何在.NET 2中顯式轉換此派生類?

說我有以下類:

public class Fruit { 
    prop string Color {get; set;} 
} 

public class Apple : Fruit { 
    public Apple() { 
     this.Color = "Red"; 
    } 
} 

public class Grape: Fruit { 
    public Grape() { 
     this.Color = "Green"; 
    } 
} 

現在,我想這樣做:

public List<Fruit> GetFruit() { 
    List<Fruit> list = new List<Fruit>(); 
    // .. populate list .. 
    return list; 
}  


List<Grape> grapes = GetFruit(); 

但是,當然,我得到Cannot implicitly convert type Fruit to Grape

我知道這是因爲我真的可以把事情搞得一團糟,如果我做的:

List<Grape> list = new List<Grape>(); 
list.add(new Apple()); 

因爲雖然兩者都是Fruit,一個Apple不是Grape。所以這是有道理的。

但我不明白爲什麼我不能做到這一點:

最起碼,我需要能夠:

List<Fruit> list = new List<Fruit>(); 
list.add(new Apple()); // will always be Apple 
list.add(new Apple()); // will always be Apple 
list.add(new Apple()); // will always be Apple 

如何做任何想法這在.NET2

感謝

編輯

對不起,我錯了。我其實可以這樣做:

.FindAll.Convert的伎倆。

+2

'prop string Color {get;設置;}'道具? – asawyer

+4

「但我不明白爲什麼我不能做到這一點」 - 到目前爲止我所知,你應該能夠做到這一點(假設你糾正Add'的'的情況下,使'Fruit'編譯) –

+0

「但我不明白爲什麼我不能做到這一點:」 - 你可以,只要你用'add',而不是'add'(不存在);最後的所有例子都很好。 –

回答

2

由於您首先需要.Net 2.0中的某些內容,我會使用FindAll來篩選,然後使用ConvertAll

List<Grape> grapes = list 
    .FindAll(delegate(Fruit f) { return f is Grape; }) 
    .ConvertAll<Grape>(delegate(Fruit f) { return f as Grape; }); 

至於你的問題:

但我不明白爲什麼我不能做到這一點:

List<Fruit> list = new List<Fruit>(); 
list.Add(new Apple()); 
list.Add(new Grape()); 

你可以做到這一點,它是完全有效,你錯了什麼(添加vs添加)?

+0

我錯了,不能插入葡萄和蘋果。您的FindAll和ConvertAll建議似乎是滿足我需求的方式。謝謝! – cbmeeks

2

即使在.NET的更高版本(枚舉類型)中,列表也不會協變。

list.Add(new Apple())等應該已經正常工作 - 這沒有問題。

對於分配,你可能需要做一些事情,如:

List<Grape> grapes = GetFruit().ConvertAll(x => (Grape)x); 

或舊的編譯:

List<Grape> grapes = GetFruit().ConvertAll<Grape>(delegate(Fruit x) { 
    return (Grape)x; 
}); 

(這是語義上相同)

4

我100%肯定你可以這樣做:

爲什麼要堅持.net 2.0有一個特別的原因嗎?

使用.net 3.5,你將有兩種可能性:

List<Apple> apples = list.OfType<Apple>().ToList(); 

這將過濾列表,並返回蘋果的列表。 你也:

List<Apple> apples = list.Cast<Apple>().ToList(); 

這不會過濾,但假設列表中的所有元素都是蘋果(和投擲和InvalidCastException的如果不是)。

+0

我必須堅持.net 2,因爲這是一個傳統的GUI應用程序,無法升級。大多數運行的機器仍然使用.net 2運行XP。 – cbmeeks

0

如果你相信葡萄將只返回Grape對象,你可以使用LINQ演員:

Enumerable.Cast Method

List<Garapes> grapes = GetFruit().Cast<Grape>().ToList(); 

你也可以使用LINQ Where採取僅是葡萄果實,在進行轉換之前

Where(f => f is Grape)

+0

需要.NET 2版本。 – cbmeeks