6

私はこの設計上の問題を何度も回避してきましたが、致命的な解決策は見つかりませんでした。

class所有者スコープで編集可能であるが、他のパブリック スコープでのみ読み取り可能なコレクションを公開したいと考えています。

試行 1:

public class MyClass
{
    private List<object> _myList = new List<object>();

    public IEnumerable<object> MyList { get { return _myList; } }
}

これに関する問題は、外部コードが次のようにキャストしてList編集できることです。

var x = ((List<object>)MyList);

試行 2:

public class MyClass
{
    private List<object> _myList = new List<object>();

    public IEnumerable<object> MyList { get { return _myList.ToList(); } }
}

このようにして、外部からの変更を防ぎますが、List何度もコピーするという不必要なオーバーヘッドが生じます。

試行 3:

public class MyClass
{
    private List<object> _myList = new List<object>();
    private ReadOnlyCollection<object> _roList = 
        new ReadOnlyCollection<object>(_myList)

    public IEnumerable<object> MyList { get { return _roList; } }
}

これは私が現在使用している標準的なソリューションですが、ReadOnlyCollection約 30% 遅くなります。

Debug Trace:
Use normal foreach on the ReadOnlyCollection
Speed(ms): 2520,3203125
Result: 4999999950000000

use<list>.ForEach
Speed(ms): 1446,1796875
Result: 4999999950000000

Use normal foreach on the List
Speed(ms): 1891,2421875
Result: 4999999950000000

これを行う「完璧な」方法はありますか?ありがとう。

4

7 に答える 7

7

列挙子を返そうとしましたか?

public class MyClass
{
    private List<object> _myList = new List<object>();

    public IEnumerable<object> MyList { get { yield return _myList.GetEnumerator(); } }
}

これはコピーを作成せず、読み取り専用であり、リストにキャストバックすることはできません。

編集:これは利回りリターンでのみ機能します。このように評価されるのは怠惰です。それがあなたにとって問題であるかどうかはわかりません。

于 2012-11-08T01:30:54.457 に答える
3

メソッドを使用List<T>.AsReadOnlyして、リストの薄い読み取り専用ラッパーを公開できます。追加のコピーはなく、呼び出し元は、メソッド内で行われた元の配列への変更を即座に「見る」ことができます。

public ReadOnlyCollection<object> MyList { get { return _myList.AsReadOnly(); } }
于 2012-11-08T01:31:55.157 に答える
1

私が普段使っていて、シンプルなのでとても気に入っている解決策は次のとおりです。

public IEnumerable<object> MyList { get { return _myList.Select(x => x); } }

ただし、Linqをサポートするバージョンの.NETを使用する必要があります

でループする場合は、foreach実際には高速です。は1ミリ秒未満、はSelect0.1秒未満ですReadOnlyCollection。についてはReadOnlyCollection、私は使用しました:

public IEnumerable<object> MyROList { get { return new ReadOnlyCollection<object>(_myList); } }
于 2012-11-08T01:45:58.487 に答える
0

List<T>.AsReadOnlyメソッドを使用してみませんか。以下のコードスニペットを参照してください。

public class MyClass
{
    private List<object> _myList = new List<object>();

    public IList<object> MyList { get { return _myList.AsReadOnly(); } }
}
于 2012-11-08T04:08:06.300 に答える
0

ReadOnlyCollection<T>ラッパーとして使用-List<T>コレクションを内部で使用します (同じ参照を使用するため、何もコピーされず、List に加えられた変更は ReadOnlyCollection にも反映されます)。

IEnumerable プロパティを提供するだけでなく、インデックス作成とカウント情報も提供されるため、優れています。

于 2012-11-08T01:33:01.017 に答える
0

IReadOnlyCollection<T>.NET Framework 4.5 では、 との 2 つの新しいインターフェイスが導入されていますIReadOnlyList<T>List<T>両方のインターフェースを実装します。

于 2012-11-08T01:59:44.287 に答える