どうすればaをに変換してList<MyObject>
からIEnumerable<MyObject>
元に戻すことができますか?
リストで一連のLINQステートメントを実行するためにこれを実行したいと思います。Sort()
どうすればaをに変換してList<MyObject>
からIEnumerable<MyObject>
元に戻すことができますか?
リストで一連のLINQステートメントを実行するためにこれを実行したいと思います。Sort()
List<string> myList = new List<string>();
IEnumerable<string> myEnumerable = myList;
List<string> listAgain = myEnumerable.ToList();
AList<T>
はであるIEnumerable<T>
ため、実際には、aをに「変換」する必要はありませList<T>
んIEnumerable<T>
。aList<T>
はであるため、型の変数にIEnumerable<T>
aを割り当てるだけで済みます。List<T>
IEnumerable<T>
逆に、すべてIEnumerable<T>
がオフコースであるとは限らないため、のmemberメソッドList<T>
を呼び出す必要があります。ToList()
IEnumerable<T>
AList<T>
は既にIEnumerable<T>
であるため、変数に対して直接 LINQ ステートメントを実行できList<T>
ます。
LINQ 拡張メソッドが表示されない場合は、ソース ファイルにディレクティブOrderBy()
がないためだと思います。using System.Linq
List<T>
ただし、LINQ 式の結果を明示的に変換する必要があります。
List<Customer> list = ...
list = list.OrderBy(customer => customer.Name).ToList()
余談ですが、標準の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
メモリ内の重複を防ぐために、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 つの理由で正しいです。これにより、一方の領域の変更が他方の領域に影響する (疎結合) を防ぐことができます。また、コンパイラを考慮してコードを設計するべきではないため、非常に読みやすくなります。
ただし、タイトなループに入っている場合や、組み込みシステムやメモリ不足のシステムで作業している場合など、コンパイラの考慮事項を考慮する必要がある場合があります。