質問

次のクラスがあります:

class SampleClass
{
   private ArrayList mMyList;

   SampleClass()
   {
       // Initialize mMyList
   }

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

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

私はオブジェクトのコピーを返すことができると思いますが、それは遅くなる可能性があり、返されたファイルを変更できないとユーザーに通知するコンパイル時エラーを提供する方法を探していますプロパティからの値。

これは可能ですか?

役に立ちましたか?

解決

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

   public IEnumerable MyList
   {
       get { return mMyList;}
   }

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

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

他のヒント

JaredParの回答をさらに詳しく説明します。彼が言ったように、ユーザーは IEnumerable ArrayList に動的にキャストできるため、実際のバッキングフィールドを返すことは完全に安全ではありません。

元のリストが変更されていないことを確認するために、次のように記述します。

public IEnumerable MyList
{
    get
    {
         foreach (object o in mMyList)
             yield return o;
    }
}

それから、完全にタイプセーフにするために、おそらく汎用リスト( IEnumerable< T> )も使用します。

ReadOnlyCollection を使用します。

  

新しいReadOnlyCollection< object>(mMyList)を返します。

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

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

と書くことができます
  

新しいReadOnlyCollection< DateTime>(mMyList.OfType< DateTime>()。ToArray())を返す

ただし、これは基になるリストで自動的に更新されず、効率も低下します(リスト全体をコピーします)。最適なオプションは、mmyListを汎用の List< T> にすることです(たとえば、 List< DateTime>

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

.NET v2.0から利用可能

    public ArrayList MyList { get; private set; }

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

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

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

   private readonly ArrayList mMyList;

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

public SampleClass()
{
   // Initialize mMyList
   mMyList = new ArrayList();
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top