我正在培訓初學者的一些核心概念的過程中的C#。在創建一個IEnumerable的隨機數字在他的代碼中的錯誤提示投IEnumerable<T>
到IEnumerator<T>
什麼演員IEnumerable <T> IEnumerator <T>做
我知道,不管這些接口的實現彼此什麼我吃驚的是,無論是ReSharper的,也不是編譯器和運行時拋出異常。
下面是一些示例代碼:
public class SomeEnumerable : IEnumerable<int>
{
private readonly IEnumerable<int> _numbers;
public SomeEnumerable()
{
_numbers = Enumerable.Range(0,10);
}
public IEnumerator<int> GetEnumerator()
{
return (IEnumerator<int>) _numbers;
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
不料GetEnumerator
- 方法編譯完全正常。當初學者誤將私人領域「_數字」ReSharper甚至建議添加我包括的顯式演員。
現在考慮下面的測試代碼:
var someEnumerable = new SomeEnumerable();
Console.WriteLine($"Number of elements: {someEnumerable.Count()}");
的Count()
- 方法調用枚舉和輸出是這樣的:
Number of elements: 0
奇怪的是,如果你改變類的構造函數,以便它使用IList<T>
作爲私人領域
public SomeEnumerable()
{
_numbers = Enumerable.Range(0,10).ToArray();
}
代碼將引發適當的InvalidCastException。
我知道Enumerable.Range()
在其實現中使用yield
語句,並且編譯器只要實現了GetEnumerator
方法就可以實現一些魔法,所以也許這是一個提示。
因此,我的問題是:
- 爲什麼劇組法律和爲什麼沒有一個警告? (編譯時間/ ReSharper的)
- 爲什麼你可以施放
IEnumerable
到IEnumerator
但不是一個IList
到IEnumerator
沒有得到一個警告(ReSharper的) - 爲什麼伯爵調用的GetEnumerator /的foreach /等。產生一個空的結果?
- 如果有很好的理由使這個工作,框架的哪個部分使用它?
一些澄清: 我知道這不應該這樣做,我知道它不能這樣工作。但我感興趣的,爲什麼代碼產生IL被編譯並執行完美的罰款,但單產這種奇怪的結果
這留下了一些未解答的問題。哪個類不指望我把它轉換爲另一種類型,爲什麼這個類會使用這兩個接口? –
@JanWolf您正在投射到'IEnumerator'的類。如果你想知道爲什麼設計課程的人按照他們的方式設計的,你可以問他們。我們只能猜測他們爲什麼選擇按照他們的方式來設計課堂。 –
Servy
我會對細節感興趣。我知道如何正確地做,這不是問題,我知道它不應該工作,這不是問題。問題是爲什麼它工作(爲什麼這個類實現兩個接口),結果的枚舉器做什麼(什麼是正在返回的枚舉器) 我知道這是不正確的代碼 –