0

1.まず、以下のコードのように IEnumerable.Add() の拡張メソッドを定義しました

 public static IEnumerable<T> Add<T, TKey>(this IEnumerable<T> enumerable, T value, Func<T, TKey> orderBy)
    {
        if (enumerable == null)
            return null;

        if (enumerable is IList<T>)
        {
            var list = enumerable as IList<T>;
            if (!enumerable.Contains(value))
            {
                list.Add(value);
                enumerable = enumerable.OrderBy(orderBy);
            }
        }
    }

2.次に、新しいアイテムがリストに追加されたときに、「日付」プロパティに従ってアイテムリストをソートするように、次のような拡張メソッドを発生させました。

   itemList.Add(item, o => o.Date);

3.やはり「itemList」がソートされていないようです。

4.拡張メソッドをたどったところ、「enumerable = enumerable.OrderBy(orderBy)」の後に「enumerable」が新しいインスタンスであり、ソートされていましたが、「リスト」はそうではありませんでした。

5.次に、並べ替えられた列挙型を「list = enumerable.ToList()」のようにリストにキャストしようとしましたが、両方(「列挙型」と「リスト」)が並べ替えられました。

6.その後、コールスタックが「itemList.Add(item, o => o.Date);」に戻ると、「itemList」がまったくソートされていませんでした!!!

誰でも私にいくつかのアドバイスを与えることができます?ありがとう、looooooooooooooooooooooooooooo!!

4

2 に答える 2

2

あなたの問題は、列挙可能への参照が参照ではなく値によって渡されていることだと思います。それが何を意味するかについての詳細は、Jon Skeet の値または参照によるパラメーターの受け渡しに関する記事を参照してください。要するに、C# はパラメーターの参照のコピーを渡すので、パラメーターに新しい値を割り当てても、渡されたオブジェクトの参照は変更されません。パラメーターを参照で渡すには、refキーワードを指定しますが、そうはならないと思います。拡張メソッドで動作します。この作業を行うことに夢中になっている場合は、リストに項目を並べ替えた順序で挿入することをお勧めします。おそらく、T に IComparable を実装する必要があります。

アップデート:

まず、Skeet の記事を参照してください。これは非常に有益であり、私はおそらく彼の半分しか理解できないでしょう。次に、オブジェクトをパラメータとしてメソッドに渡すと、参照のコピーが渡されます。これは、オブジェクトのメンバーに引き続きアクセスできることを意味しますが、値の型がコピーによって渡されるのと同じ方法で、参照を変更する (つまり、新しい値を割り当てる) と、元の参照は変更されません。指定refすることは、参照に参照を渡すことを意味し、参照を変更する (参照に値を割り当てる) と、元のオブジェクトに影響します。

于 2012-05-04T01:24:22.630 に答える
1

OrderBy も ToList もソース リストには影響しません。これを行ったとき:list=enumerable.ToList()変数を変更して、まったく新しいリストインスタンスを指すようにしました。

この方法はやりすぎのように思えます。別の操作として追加と並べ替えを続けます。これが IEnumerable を拡張するが、ターゲットが IList でない場合は黙って何もしないという事実は、コードのにおいです。

于 2012-05-04T01:25:21.287 に答える