2009-10-29 49 views
2

我有一個名爲Media的bas類,其中有兩個繼承自它的類,PhotoVideo。我正在嘗試爲媒體基類創建一個集合以容納這些照片和視頻對象。所以,我創建了一個MediaList類,如下所示:使用yield return返回從基類型繼承的對象

public class MediaList: ICollection<Media> 
{ 
    private readonly XElement _mediaElement; 

    public MediaList(XElement mediaElement) 
    { 
     _mediaElement = mediaElement;    
    } 

    public IEnumerator<Media> GetEnumerator() 
    { 
     foreach (XElement element in _mediaElement.Elements()) 
     { 
      Media media; 
      switch (element.Name.LocalName) 
      { 
       case "video": 
        media = new Video(element); 
        break; 
       case "photo": 
        media = new Photo(element); 
        break; 
       default: 
        media = null; 
        break; 
      } 
      yield return media; 
     } 
    } 

    //Rest of ICollection Implementation 
} 

當我遍歷列表中我得到以下異常:

值「Tool.Photo」的類型是不是「Tool.Video」,不能用於這個通用集合。

如果我返回Media對象,爲什麼它拋出異常?有沒有更好的方法來解決這個問題?

+0

媒體摘要? – 2009-10-29 13:37:56

+0

沒有媒體不是摘要 – Geoff 2009-10-29 13:39:11

+2

您確定代碼完全一樣嗎?您能否顯示客戶端代碼 - 介紹客戶端代碼中的(合/對)差異。 – 2009-10-29 13:43:42

回答

2

你的錯誤是在其他地方。只要Video和Photo從媒體繼承,你所寫的就沒有問題。也許你試圖把它錯誤地放在別的地方。

+0

經過挖掘,你是對的,我的問題在別處。問題在哪裏?嘆息回到步進代碼:-) – Geoff 2009-10-29 14:00:00

1

不應與收益率回報的方法輸入返回IEnumerable<Media>,不IEnumerator<Media>

但更基本,這種模式給我留下難聞的氣味。每次你對這個「集」使用的foreach,您將創建(實例)在_mediaElement.Elements()列表中的每個PhotoVideo對象的新實例。這真的是你想要的嗎?

+0

他沒有什麼好的。 – 2009-10-29 13:48:47

+0

不是返回Media對象的yield返回值嗎? (不是媒體對象的枚舉器)。 – 2009-10-29 13:50:38

+0

枚舉器是在調用foreach時創建的狀態維護對象,用於跟蹤集合中的哪個對象是當前對象,並在每次迭代迭代時將該狀態遞增到下一個對象。使用yield return時,c#編譯器爲您創建一個枚舉器。 – 2009-10-29 13:53:33

0

貌似你試圖添加Media實例爲Video集合,它吹起來,因爲一個或更多的人是Photo - 你試圖照片添加到視頻採集。錯誤在您的客戶端代碼中,而不是在生成的枚舉器中。

3

嘗試......

class Program 
{ 
    static void Main(string[] args) 
    { 
     var array = new string[] { "video", "photo", "hurf", "photo" }; 
     var ml = new MediaList(array); 
     foreach(var element in ml) 
      Console.WriteLine(element.GetType().Name); 
     Console.Read(); 
    } 
} 

public class Media { } 
public class Video : Media { } 
public class Photo : Media { } 

public class MediaList 
{ 
    private string[] elements; 
    public MediaList(string[] elements) { this.elements = elements; } 
    public IEnumerator<Media> GetEnumerator() 
    { 
     foreach (string s in elements) 
      switch (s) 
      { 
       case "video": 
        yield return new Video(); 
        break; 
       case "photo": 
        yield return new Photo(); 
        break; 
      } 
    } 
} 

你可以拍這個到一個控制檯應用程序進行測試。

注意到一些不同的東西。 第一個,你永遠不會返回null。這與您的問題沒有任何關係,但沒有人希望枚舉返回null,並且稍後會導致您的問題。 第二個,我沒有演出我回來的東西。所有的轉換都是隱含的,或者由編譯器處理,所以我沒有必要這樣做。 第三,這個編譯和工作,你的原始代碼。您的問題正在其他地方發生,因爲您會發現如果將此代碼放入控制檯應用程序並進行測試。

+0

+1這是我在開始時的確切代碼,直到我把整個錯誤的兔子都拖下來:-) – Geoff 2009-10-29 14:06:58