ソートが失敗するとき §
ここに、1, 4, 2, 3という値を持ったList<int>クラスのオブジェクトがあるとします。
これをソートするのは簡単です。Sortメソッドを呼べば1, 2, 3, 4になります。
サンプルソースのsort1メソッドの通りです。
しかし、LINQのOrderByメソッドを使おうと思ってサンプルソースのsort2メソッドのように書き換えるとソートしません。
ソートしない理由は簡単で、Sortメソッドは元データを書き換えますが、OrderByメソッドはソート結果を別の列挙オブジェクトとして返すだけだからです。そして、いくら引数を書き換えても元のデータは書き換わりません。
どうすれば良いでしょうか?
サンプルソースのsort3メソッドのようにrefキーワードを付ければ元データの変数が書き換わるので意図通りに動きます。
罠の数々 §
- サンプルソースのsort3メソッドはオブジェクトの中味を修正したわけではなく、あくまで変数を書き換えただけである。サンプルソースのsort1メソッドと厳密に同じ動作ではないことに注意しよう
参考リンク §
List<T>.Sort メソッド
Enumerable.OrderBy メソッド
Enumerable.ToList<TSource>(IEnumerable<TSource>) メソッド
Sortメソッド、OrderBy メソッド、ソートという機能は同じだが出自も役割も違う。どこがどう違うのか上記のリンクから確かめてみよう。
リポジトリ §
https://github.com/autumn009/cshowto
sort §
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
private static void sort1(List<int> list)
{
list.Sort();
}
private static void sort2(List<int> list)
{
list = list.OrderBy(c => c).ToList();
}
private static void sort3(ref List<int> list)
{
list = list.OrderBy(c => c).ToList();
}
static void Main()
{
var list1 = new List<int>() { 1, 4, 2, 3 };
sort1(list1);
foreach (var item in list1) Console.Write(item);
Console.WriteLine();
var list2 = new List<int>() { 1, 4, 2, 3 };
sort2(list2);
foreach (var item in list2) Console.Write(item);
Console.WriteLine();
var list3 = new List<int>() { 1, 4, 2, 3 };
sort3(ref list3);
foreach (var item in list3) Console.Write(item);
Console.WriteLine();
}
}
実行結果
1234
1423
1234