web-dev-qa-db-ja.com

IEnumerable <T>への配列のキャスト

基本的なEmployeeクラスがあるとします:

_class Employee
{
   public string Name;
   public int Years;
   public string Department;
}
_

それから(別のクラスで)次のコードフラグメントがあります(最後を除いてすべてを理解していると思います):

配列イニシライザーが、割り当てられている従業員変数と同じ型のEmployeeオブジェクトの配列を作成するため、次のコードフラグメントが機能すると考えています。

_Employee[] workforceOne = new Employee[] {
   new Employee() { Name = "David", Years = 0, Department = "software" },
   new Employee() { Name = "Dexter", Years = 3, Department = "software" },
   new Employee() { Name = "Paul", Years = 4, Department = "software" } };
_

その後、次のコードフラグメントがあります。 Employeeオブジェクトの暗黙の配列はIEnumerableを実装するArray()クラスの実装であるため、これが機能すると考えています。したがって、これが配列をIEnumerableに割り当てることができる理由だと思いますか?

_IEnumerable workforceTwo = new Employee[] {
   new Employee() { Name = "David", Years = 0, Department = "software" },
   new Employee() { Name = "Dexter", Years = 3, Department = "software" },
   new Employee() { Name = "Paul", Years = 4, Department = "software" } };
_

次に、このコードの断片があります:

_IEnumerable<Employee> workforceThree = new Employee[] {
   new Employee() { Name = "David", Years = 0, Department = "software" },
   new Employee() { Name = "Dexter", Years = 3, Department = "software" },
   new Employee() { Name = "Paul", Years = 4, Department = "software" } };
_

このコードの一部が機能する理由がわかりませんか? _IEnumerable<Employee>_はIEnumerableを継承します(そしてGetEnumerator()メソッドをオーバーライド(またはオーバーロードします))が、すべきではありませんしたがって、上記のようにキャストするにはキャストが必要です:

_//The cast does work but is not required
IEnumerable<Employee> workforceFour = (IEnumerable<Employee>)new Employee[] {
   new Employee() { Name = "David", Years = 0, Department = "software" },
   new Employee() { Name = "Dexter", Years = 3, Department = "software" },
   new Employee() { Name = "Paul", Years = 4, Department = "software" } };
_

配列はIEnumerable型から_IEnumerable<Employee>_型に暗黙的にダウンキャストされているようですが、型をより具体的なものに変換する必要があるときは、明示的なキャストが必要でした。

たぶん私はここでの私の理解で簡単なものを見逃していますが、誰かがこれについての私の理解を助けてくれますか?.

ありがとうございました。

71
Dangerous

ドキュメント から:

.NET Frameworkバージョン2.0では、ArrayクラスはSystem.Collections.Generic.IList<T>System.Collections.Generic.ICollection<T>、およびSystem.Collections.Generic.IEnumerable<T>汎用インターフェース。実装は実行時に配列に提供されるため、ドキュメント作成ツールには表示されません。結果として、ジェネリックインターフェイスはArrayクラスの宣言構文に表示されず、ジェネリックインターフェイスタイプに配列をキャストすることによってのみアクセスできるインターフェイスメンバの参照トピックはありません(明示的なインターフェイス実装)。

したがって、Employee[]実装IEnumerable<Employee>

101
Heinzi

従業員の配列はデフォルトでIEnumerable<Employee>IEnumerableを実装します

4
Dennis Traub

一部の文をdowncastedする必要がある場合、明示的なキャストが必要です。これは、オブジェクトをより特殊なタイプにキャストすることです(オブジェクトがそのような特殊なタイプの場合)。

一方、upcasting(あまり特殊化されていない型へのキャスト)、明示的なキャストは必要ありませんが、明示的にキャストすることはできます(役に立たないだけです) )。

ArrayはIEnumerableIEnumerable<T>を実装しているため、コードでpcastを実行しています。つまり、IEnumerable<T>に明示的にキャストする必要はありません。

3