0

List から継承する C# ライブラリ クラスがありますが、List.Contains が遅いため低速です。多くのクライアント コードがこのクラスに依存しており、インターフェイスを変更するには複雑すぎるため、Dictionary や HashSet などの他のクラスから継承するようにクラスを変更することはできません。このメソッドを変更せずに高速化する簡単な方法はありますか? 一部のリストは非常に大きいため、メモリ内に 2 つのコピーは必要ありません。List のすべてのメソッドもオーバーライドしたくありません。

public class UniqueList<T> : List<T>, IList<T>
{
    public new void Add(T item)
    {
        if (!this.Contains(item) && item != null)
        {
            base.Add(item);
        }
    }
4

3 に答える 3

2

リストからの継承は、クラスがクライアント コードによってどのように使用されるかを制御できないため、非常に悪い考えです。

List.Contains はO(n)操作です。Dictionary.ContainsKey はO(1)であるため、 Dictionary を使用することが最善のアドバイスだと思いますが、本当に使用したくない場合は、リストをソートしてO(log n)を取得することもできます。

public void Add(T item)
{
    int index = BinarySearch(item);
    if (index < 0)
    {
        Insert(~index, item);
    }
}

要素が既にリストにある場合、BinarySearch はそのインデックスを返します。要素がリストにない場合、BinarySearch メソッドは、二分探索メソッドに渡した要素よりも大きい最初の要素のインデックスの 2 進補数である負の数を返します。

BinarySearch は、T が何であるかによって異なるため、シナリオでは使用できない場合があります: http://msdn.microsoft.com/en-us/library/w4e7fxsh.aspx

このメソッドは、型 T の既定の比較演算子 Comparer.Default を使用して、リスト要素の順序を決定します。Comparer.Default プロパティは、型 T が IComparable ジェネリック インターフェイスを実装しているかどうかを確認し、利用可能な場合はその実装を使用します。そうでない場合、Comparer.Default は、型 T が IComparable インターフェイスを実装しているかどうかを確認します。型 T がどちらのインターフェイスも実装していない場合、Comparer.Default は InvalidOperationException をスローします。

于 2013-03-05T11:38:40.277 に答える
2

要するにNo.

から継承しList<>ているため、本質的にねじ込まれています。Contains メソッドをシャドウしても、クライアント コードが aUniqueListを受け入れるメソッドに a を渡すのを止めることはできないList<>ため、新しい Contains が非表示になり、既存の1。

これを難しい方法で修正し、 の継承を削除し、List<>独自の Contains を実装し、リストから必要なメソッドを再実装し (内部的にprivate List<>はストレージに a を使用し、必要に応じて単純にデリゲートすることができます)、すべてを修正する必要があります。この変更が壊れるコード。

あなたが物事を壊している間、インターフェイスに対する開発を促進するC5コレクションクラスを見ることができ、この問題にぶつからないようにします(私は知っています、馬がボルトで固定された後に納屋のドアをもっと閉めます)

これがあなたが探している答えではないことはわかっていますが、あなたが望む答えは得られません (これを回避するプログラムを作成する方法は実際にはありません。Castle Interceptorsのようなものを試すことはできますが、私はしません)この場合はうまくいくと思います...しかし、うまくいかないかどうかはわかりません)

繰り返しますが、実際に助けることができなかったことをお詫び申し上げます。

于 2013-03-05T11:39:07.493 に答える
0

クラス レベルのプライベート ディクショナリを用意し、ディクショナリで見つからない場合は最初にディクショナリをチェックインしてから、リストに移動してチェックします。最適化は純粋なソリューションではないだけであり、追加のメモリが必要になります。

于 2013-03-05T10:15:26.613 に答える