0
  • まとめ

    オブジェクトが配列として表現できない場合は無視してください。次のような拡張 (静的) メソッドを定義することは可能ですか?

    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>でしょうか?

4

3 に答える 3

1

残念ながら、IEnumeratorジェネリックスよりも前のものであるため、型情報は含まれていません。あなたが達成しようとしているこの一般的な実装を試して強制するIEnumerator GetEnumerator()ことStringはそれほど魅力的ではありません。

C#を実行してから長い時間が経ちましたが、想像してみてください。

public static TElement ToArray<TSource>(this IEnumerable<TElement> source);

...次のように問題ないはずです:

public static TElement[] ToArray<TElement>(this IEnumerable<TElement> source);

拡張メソッドについて覚えておくべき重要なことは、それらが単なるシンタックスシュガーであるということです。それらは実際に固執したり、装飾しているタイプに注入されたりすることはありません。これらは、コンパイル時に静的メソッド呼び出しに置き換えられます。延長方法でのマイレージ異なります。

于 2012-12-30T06:24:59.457 に答える
1

あなたの質問は具体的に何ですか?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 に組み込まれている拡張機能は、何も定義しなくても既に使用できます。stringstringIEnumerable<string>IEnumerable<char>.ToArray()string

于 2013-01-14T12:41:21.067 に答える
1

コンパイル時には不明であり、知ることもできません。

たとえば、次のことができます。

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();

基本的に、ユーザー入力に応じてmyCollectionaList<string>または an のいずれかになりますint[]。2 つの型は、列挙可能であることを除いて、ほとんど共通点がありません。

したがって、メソッドが機能するためには、代わりにToArrayを使用してタイプ セーフとジェネリックを導入するか、メソッドの戻り値の型などのオブジェクトのコレクションを使用することができます。IEnumerable<T>IEnumerableobject[]

于 2013-01-14T13:25:18.480 に答える