19

私は次のクラスを持っています:

class SampleClass
{
   private ArrayList mMyList;

   SampleClass()
   {
       // Initialize mMyList
   }

   public ArrayList MyList
   {
       get { return mMyList;}
   }
}

ユーザーがmMyListを取得できるようにしたいので、プロパティを介して「get」を公開しましたが、オブジェクト(つまり、MyList.Add(new Class());)に変更を加えて作成したくありません私のクラスに戻ります。

私はオブジェクトのコピーを返すことができると思いますが、それは遅いかもしれません.財産。

これは可能ですか?

4

8 に答える 8

25

ArrayList を使用すると、BCL に読み取り専用の非ジェネリック コレクション クラスがないため、かなり制限されます。手っ取り早い解決策は、IEnumerable の型を返すことです。

   public IEnumerable MyList
   {
       get { return mMyList;}
   }

これは、誰かが ArrayList にキャストするのを実際には妨げませんが、デフォルトでは編集も許可しません

ArrayList.ReadOnly を呼び出すと、実質的に読み取り専用リストを返すことができます。ただし、戻り値の型は ArrayList であるため、ユーザーは .Add でコンパイルできますが、実行時エラーが発生します。

于 2009-03-06T16:17:40.167 に答える
19

ArrayList.ReadOnly()メソッドを使用して、リストの読み取り専用ラッパーを構築して返します。リストをコピーするのではなく、読み取り専用のラッパーを作成するだけです。コンパイル時のチェックを取得するには、@Jared が示唆するように、読み取り専用ラッパーを IEnumerable として返したいと思うでしょう。

public IEnumerable MyList
{
     get { return ArrayList.ReadOnly(mMyList); }
}

読み取り専用のコレクションは、コレクションの変更を防止するラッパーを持つコレクションです。基になるコレクションに変更が加えられると、読み取り専用コレクションにそれらの変更が反映されます。

このメソッドは O(1) 操作です。

参照

于 2009-03-06T16:18:51.477 に答える
4

を使用しReadOnlyCollectionます。

return new ReadOnlyCollection<object>(mMyList)

フィールドを作成することもできReadOnlyCollection、基になるリストの変更が自動的に反映されます。これが最も効率的なソリューションです。

mMyListに含まれるオブジェクトのタイプが1つだけであることがわかっている場合(たとえば、DateTimesしか含まれていない場合)、ReadOnlyCollection<DateTime>タイプの安全性を高めるために(または他のタイプの)オブジェクトを返すことができます。C#3を使用している場合は、次のように記述できます。

return new ReadOnlyCollection<DateTime>(mMyList.OfType<DateTime>().ToArray())

ただし、これは基になるリストで自動的に更新されず、効率も低下します(リスト全体がコピーされます)。最良のオプションは、mMyListをジェネリックにすることですList<T>(例List<DateTime>:)

于 2009-03-06T17:50:02.583 に答える
4

List(T).AsReadOnly メソッド=)

于 2009-03-06T17:54:46.207 に答える
1

戻り値を読み取り専用コレクションにラップする必要があります。

于 2009-03-06T16:17:45.987 に答える
0

.NET v2.0から利用可能

    public ArrayList MyList { get; private set; }
于 2013-03-25T20:50:05.323 に答える
-3

次のように、プロパティを Sealed (または VB.NET では NotInheritable) および読み取り専用にするだけです。

   public sealed readonly ArrayList MyList
   {
       get { return mMyList;}
   }

また、バッキング フィールドを読み取り専用にすることを忘れないでください。

   private readonly ArrayList mMyList;

ただし、mMyList の値を初期化するには、次の例のように、コンストラクターでのみ初期化する必要があります。

public SampleClass()
{
   // Initialize mMyList
   mMyList = new ArrayList();
}
于 2009-03-06T16:42:44.507 に答える