まとめ
オブジェクトが配列として表現できない場合は無視してください。次のような拡張 (静的) メソッドを定義することは可能ですか?
public static ? ToArray<TSource>(this TSource source);
オブジェクトが要素のシーケンスで構成されている場合、オブジェクトの配列を返しますか? はいの場合、それは何でしょう
?
か?説明
私は次の宣言について考えました:
public static TElement[] ToArray<TElement>(this IEnumerable<TElement> source); public static ? ToArray<TSource>(this IEnumerable source);
しかし、未知のクラスが
IEnumerable<T>
orを実装しているに違いないとは思いませんIEnumerable
。?
一般的な定義から外れている場合は、 を定義することさえできませんIEnumerable
。そして、私は
Array
クラスについても考えました:public static Array ToArray<TSource>(this TSource source);
しかし、それは要素の型がコンパイル時に不明だったことを意味します。
クラスを実装せずに、コンパイル時に要素の型を知ることは可能
IEnumerable<T>
でしょうか?
3 に答える
残念ながら、IEnumerator
ジェネリックスよりも前のものであるため、型情報は含まれていません。あなたが達成しようとしているこの一般的な実装を試して強制するIEnumerator GetEnumerator()
ことString
はそれほど魅力的ではありません。
C#を実行してから長い時間が経ちましたが、想像してみてください。
public static TElement ToArray<TSource>(this IEnumerable<TElement> source);
...次のように問題ないはずです:
public static TElement[] ToArray<TElement>(this IEnumerable<TElement> source);
拡張メソッドについて覚えておくべき重要なことは、それらが単なるシンタックスシュガーであるということです。それらは実際に固執したり、装飾しているタイプに注入されたりすることはありません。これらは、コンパイル時に静的メソッド呼び出しに置き換えられます。延長方法でのマイレージは異なります。
あなたの質問は具体的に何ですか?IEnumerable
の要素の型がコンパイル時に常に認識されているかどうかを尋ねている場合、答えは「いいえ、常に認識されているとは限りません」です。非ジェネリック IEnumerable は、要素の型を強制しません。foreach
これが、任意のループを定義できる理由ですIEnumerable
。
IEnumerable items = GetItems();
foreach(SomeClass item in items)
{
...
}
InvalidCastException
しかし、これはの要素の 1 つをitems
にキャストできない場合にスローしSomeClass
ます。
ちなみに、次のようなメソッドを定義すると:
public static TElement[] MyToArray<TElement>(this IEnumerable<TElement> source);
次に、.NET 2.0 と 3.0、および3.5+で実装されているため、.NET 2.0+ で呼び出すことができます。実際、.NET に組み込まれている拡張機能は、何も定義しなくても既に使用できます。string
string
IEnumerable<string>
IEnumerable<char>
.ToArray()
string
コンパイル時には不明であり、知ることもできません。
たとえば、次のことができます。
IEnumerable myCollection;
string discriminator = Console.ReadLine();
if (discriminator == "string")
{
myCollection = new List<string>{"One", "Two", "Three", "Four"};
}
else
{
myCollection = new int[]{1, 2, 3, 4};
}
//what should be the type of the elements variable
var elements = myCollection.ToArray();
基本的に、ユーザー入力に応じてmyCollection
aList<string>
または an のいずれかになりますint[]
。2 つの型は、列挙可能であることを除いて、ほとんど共通点がありません。
したがって、メソッドが機能するためには、代わりにToArray
を使用してタイプ セーフとジェネリックを導入するか、メソッドの戻り値の型などのオブジェクトのコレクションを使用することができます。IEnumerable<T>
IEnumerable
object[]