web-dev-qa-db-ja.com

List <T>とIEnumerable <T>を自由に変換します

List<MyObject>IEnumerable<MyObject>に変換してから元に戻すにはどうすればよいですか?

リストで一連のLINQステートメントを実行するために、これを実行したいと思います。 g。 Sort()

102
TK.
List<string> myList = new List<string>();
IEnumerable<string> myEnumerable = myList;
List<string> listAgain = myEnumerable.ToList();
146
Tamas Czinege

List<T>IEnumerable<T>であるため、実際にはList<T>IEnumerable<T>に「変換」する必要はありません。 List<T>IEnumerable<T>であるため、List<T>IEnumerable<T>型の変数に単純に割り当てることができます。

逆に、すべてのIEnumerable<T>List<T>オフコースではないため、IEnumerable<T>ToList()メンバーメソッドを呼び出す必要があります。

21

List<T>はすでにIEnumerable<T>であるため、List<T>変数で直接LINQステートメントを実行できます。

OrderBy()のようなLINQ拡張メソッドが表示されない場合は、ソースファイルにusing System.Linqディレクティブがないためだと思います。

ただし、LINQ式の結果をList<T>に明示的に変換して戻す必要があります。

List<Customer> list = ...
list = list.OrderBy(customer => customer.Name).ToList()
9
Dan Berindei

余談:(前の例のように)標準のLINQ演算子は既存リストを変更しないことに注意してください-list.OrderBy(...).ToList()は並べ替えられたシーケンスに基づいて新しいリストを作成します。ただし、List<T>.Sortでラムダを使用できる拡張メソッドを作成するのは非常に簡単です。

static void Sort<TSource, TValue>(this List<TSource> list,
    Func<TSource, TValue> selector)
{
    var comparer = Comparer<TValue>.Default;
    list.Sort((x,y) => comparer.Compare(selector(x), selector(y)));
}

static void SortDescending<TSource, TValue>(this List<TSource> list,
    Func<TSource, TValue> selector)
{
    var comparer = Comparer<TValue>.Default;
    list.Sort((x,y) => comparer.Compare(selector(y), selector(x)));
}

次に使用できます:

list.Sort(x=>x.SomeProp); // etc

これは、List<T>.Sortが通常行うのと同じ方法でexistingリストを更新します。

5
Marc Gravell

List<T>からIEnumerable<T>への変換

List<T>IEnumerable<T>(およびIList<T>, ICollection<T>などの他の多く)を実装するため、既にIEnumerable<T>であるため、ListをIEnumerableに戻す必要はありません。

例:

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
}

Person person1 = new Person() { Id = 1, Name = "Person 1" };
Person person2 = new Person() { Id = 2, Name = "Person 2" };
Person person3 = new Person() { Id = 3, Name = "Person 3" };

List<Person> people = new List<Person>() { person1, person2, person3 };

//Converting to an IEnumerable
IEnumerable<Person> IEnumerableList = people;

Enumerable.AsEnumerable()メソッドも使用できます

IEnumerable<Person> iPersonList = people.AsEnumerable();

IEnumerable<T>からList<T>への変換

IEnumerable<Person> OriginallyIEnumerable = new List<Person>() { person1, person2 };
List<Person> convertToList = OriginallyIEnumerable.ToList();

これは Entity Framework で便利です。

1
Nipuna

メモリの重複を防ぐために、resharperはこれを提案しています。

List<string> myList = new List<string>();
IEnumerable<string> myEnumerable = myList;
List<string> listAgain = myList as List<string>() ?? myEnumerable.ToList();

.ToList()は、新しい不変リストを返します。したがって、listAgainを変更しても、@ Tamas Czinegeの回答のmyListには影響しません。ほとんどの場合、これは少なくとも2つの理由で正しいです。これは、一方の領域が他方の領域に影響するのを防ぐのに役立ちます(疎結合)。

しかし、コンパイラの考慮事項を考慮すべき、タイトループにある、組み込みシステムまたは低メモリシステムで作業しているなど、特定のインスタンスがあります。

0
TamusJRoyce