6
private static void PrintEachItemInList<T>(T anyList) 
Where T:System.Collections.Generic.List<T>
{    
    foreach (var t in T)
    {
        //Do whatever
    }
}

T上記のコード (これは間違っています)では、リストである制約を設定するためにやりたいことがすべてあります。

目的は、この例を機能させることではなく、型がリストであるという制約をどのように設定できるかを理解することです。私はジェネリックのアマチュアであり、物事を理解しようとしています:(

4

5 に答える 5

7

次のように、 2 つの型パラメーターが必要な場合があります。

private static void PrintEachItemInList<TList, TItem>(TList anyType) 
  where TList : System.Collections.Generic.List<TItem>

これは、実際に から派生したクラスを使用する場合に便利ですList<>リストとして機能するものが必要な場合は、代わりにインターフェイス に制限することを検討してください。IList<>その後、List<>、一次元配列、およびインターフェイスを実装するカスタム クラスで機能します (ただし、必ずしも から派生するとは限りませんList<>)。

編集:コメントで指摘されているように、コンパイラは 2 つの型引数を推測しないため、このメソッドは使いにくいため、メソッドを呼び出すときに明示的に指定する必要があります。

使用することを検討してください:

private static void PrintEachItemInList<TItem>(List<TItem> anyType) 

a から派生するものはすべて にList<>代入可能であるためList<>、派生クラスを引数としてメソッドを呼び出すことができ、多くの場合、型TItemはコンパイラによって自動的に推測されます。

インターフェイスの使用を検討してIList<>ください。

やりたいことがすべてリストから読み取らIReadOnlyList<TItem>れる場合は、代わりに を使用しIList<TItem>ます。これは、発信者のリストを変更しないことを発信者に知らせます。呼び出すときにキャスト構文はまだ必要ありません。たとえば、PrintEachItemInList(new[] { 2, 3, 5, 7, });. この型IReadOnlyList<>は .NET バージョン 4.5 で新しく追加されました。

リストから読み取るだけで、インデクサーを使用したくない場合 (no anyType[idx])、.Countプロパティを使用したくない場合、実際にforeachはリストを使用するだけで済みます。 、使用IEnumerable<TItem>。繰り返しますが、ユーザーのリストを変更しないことを示しています。

IReadOnlyList<>IEnumerable<>はどちらも、ジェネリック引数 (型パラメーター) で共変です。

于 2013-02-11T16:56:50.587 に答える
6

入力パラメーターを として宣言しますIList<T>。入力シーケンスをできるだけ抽象化したい場合は、IEnumerable<T>代わりに使用しますIList<T>

private static void PrintEachItemInList<T>(IList<T> sequence)
{
    foreach (T element in sequence)
    {
        //Do whatever
    }
} 
于 2013-02-11T16:55:19.540 に答える
3

関数は単純にリストを受け入れる必要があり、制約は必要ありません。

private static void PrintEachItemInList<T>(IList<T> list) 
{
    foreach (var t in list)
    {
        //Do whatever
    }
}

ただし、リストを反復処理するだけの場合は、パラメーターの型を次の基本インターフェイスのいずれかに変更することで、コードをより一般的にすることができます。

  • IEnumerable<T>- 許可しますforeach
  • IReadOnlyCollection- 上記と同じで、コレクション内の要素の数を提供します
  • IReadOnlyList- 上記と同じで、インデックスによる要素アクセスを許可します
  • ICollection<T>-IEnumerable<T>要素数と、要素を追加および削除するためのメソッドを提供する です
  • IList<T>- 上記と同じで、インデックスによって要素を追加および削除できます
于 2013-02-11T16:55:30.537 に答える
1

通常、これは次のように記述します。

private static void PrintEachItemInList<T>(List<T> anyType)
{
  // do work
}

ただし、この場合は、IEnumerable<T>代わりに次を使用することをお勧めします。

private static void PrintEachItemInList<T>(IEnumerable<T> anyType)
{
  // do work
}

これにより、引き続き使用できますforeachが、メソッドをより柔軟にすることができます。これは、機能するList<T>だけでなく、実装する他のコレクションも機能するためIEnumerable<T>です。メソッド内にリストのセマンティクスが必要な場合は、 を使用できますIList<T>が、サンプル コード (およびメソッド名)IEnumerable<T>がより適切であることを示唆しています。

于 2013-02-11T16:55:26.430 に答える