2013-04-20 63 views
0

的GetEnumerator強制轉換爲接口失敗
沒有編譯器錯誤
與郵件索引無窮運行故障
如果我使用結構Word1252直接與無界面它的工作原理List泛型GetEnumerator的強制轉換爲接口失敗

namespace WordEnumerable 
{ 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
      WordEnum wordEnum = new WordEnum(); 
      Debug.WriteLine(wordEnum[0].GetType().ToString()); 
      Debug.WriteLine(wordEnum[0].Value); 
      Debug.WriteLine(wordEnum.Count.ToString()); 
      foreach (iWord w in wordEnum) // fails here 
      { 
      } 
     } 
    } 
} 
public interface iWord 
{ 
    Int32 Key { get; } 
    String Value { get; } 
} 
public class WordEnum : IEnumerable<iWord> 
{ 
    private static List<Word1252> words1252 = new List<Word1252>(); 
    IEnumerator<iWord> IEnumerable<iWord>.GetEnumerator() 
    { 
     return ((IEnumerable<iWord>)words1252).GetEnumerator(); 
    } 
    public struct Word1252 : iWord 
    { 
     public UInt64 packed; 
     public Int32 Key { get { return (Int32)((packed >> 27) & ((1 << 25) - 1)); } } 
     public Byte Length { get { return (Byte) ((packed >> 59) & ((1 << 5) - 1)); } } 
     public String Value { get { return Key.ToString(); } } 
     public Word1252(UInt64 Packed) { packed = Packed; } 
    } 

回答

1

簡而言之,這是upcastingIEnumerable<Word1252>IEnumerable<IWord>,

這就需要covariance工作。

即使IEnumerable的被標記爲out(協)
協方差不適合工作「價值型」 - 即結構你有 接口定義。

例如,看到...

Is this a covariance bug in C# 4?
(或有點不同,但歸結爲同一個問題)
Why cannot IEnumerable<struct> be cast as IEnumerable<object>?

要解決你可以定義列表像

private static List<iWord> words1252 = new List<iWord>(); 

或定義你的這樣的統計員:

IEnumerator<iWord> IEnumerable<iWord>.GetEnumerator() 
{ 
    foreach (var word in words1252) 
     yield return word; 
} 
+0

他們都工作感謝。隨着私有靜態列表 words1252 =新名單();我必須投入Word1252以獲得內部資源,但我會採取這種方式。你知道如果foreach有性能損失嗎?如果不是,我寧願使用它。 – Paparazzi 2013-04-21 00:15:11

+0

歡迎您。 「foreach」更好,我同意。有沒有性能影響有(或某些運算最多額外) - 這是「屈服」,因爲它去 - 所以基本上做和原來一樣「枚舉」 - 這是「鑄造」內'調查員已知和接受的方法(即當你需要返回不同的物品 - 但無法施放時) – NSGaga 2013-04-21 00:18:27

相關問題