سؤال

ولدي الطبقة التالية:

class SampleClass
{
   private ArrayList mMyList;

   SampleClass()
   {
       // Initialize mMyList
   }

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

وأريد المستخدمين لتكون قادرة على الحصول على mMyList الذي هو السبب في أنني فضحت "الحصول على" عبر خاصية ولكن أنا لا أريد التغييرات التي تجريها على كائن (أي MyList.Add (الفئة الجديدة ())؛). لجعل طريقها مرة أخرى إلى صفي.

واعتقد انني يمكن إرجاع نسخة من الكائن ولكن ذلك قد يكون بطيئا وأنا أبحث عن وسيلة من شأنها أن توفر خطأ وقت الترجمة إعلام المستخدم بأن عليهم أن لا نتوقع أن تكون قادرا على تعديل عاد القيمة من الملكية.

هل هذا ممكن؟

هل كانت مفيدة؟

المحلول

ومع أحد ArrayList هل تقتصر إلى حد ما لأنه لا يوجد فئة مجموعة غير عامة للقراءة فقط في BCL. الحل السريع والقذر هو العودة نوع من IEnumerable.

   public IEnumerable MyList
   {
       get { return mMyList;}
   }
سوف

وهذا لا يمنع في الواقع شخص من الإدلاء إلى ArrayList لكنها لن تسمح التعديلات افتراضيا إما

ويمكنك العودة قائمة للقراءة فقط على نحو فعال من خلال الدعوة ArrayList.ReadOnly. ومع ذلك فإنه في نوع الإرجاع هو ArrayList وبالتالي فإن المستخدم سوف لا يزال قادرا على ترجمة مع. إضافة كنها شأنه أن يؤدي إلى خطأ وقت التشغيل.

نصائح أخرى

وفقط للتوسع في الجواب JaredPar ل. كما قال، والعودة في مجال الدعم الفعلي ليس آمنة تماما، لأن المستخدم لا يزال قادرا على الإدلاء حيوي IEnumerable مرة أخرى إلى ArrayList.

وأود أن أكتب شيئا مثل هذا للتأكد من يتم إجراء أية تعديلات على القائمة الأصلية:

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

وبعد ذلك مرة أخرى، وأود أن probabily أيضا استخدام قائمة عامة (IEnumerable<T>) أن اكتب آمنة تماما.

استخدم لReadOnlyCollection.

<اقتباس فقرة>   

وreturn new ReadOnlyCollection<object>(mMyList).

ويمكنك أيضا جعل ReadOnlyCollection حقل، وسوف تعكس التغيرات في القائمة الأساسية تلقائيا. هذا هو الحل الأكثر كفاءة.

إذا كنت تعرف أن mMyList يحتوي فقط على نوع واحد من وجوه (على سبيل المثال، ليس لديه شيء لكن DateTimes)، يمكنك إرجاع ReadOnlyCollection<DateTime> (أو أي نوع آخر) لسلامة نوع إضافية. إذا كنت تستخدم C # 3، يمكنك ببساطة كتابة

<اقتباس فقرة>   

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

ولكن، وهذا سوف يتم تلقائيا تحديث مع القائمة الأساسية، وأيضا أقل كفاءة (وسوف نسخ قائمة كاملة). الخيار الأفضل هو جعل mMyList على List<T> عامة (على سبيل المثال، وهو List<DateTime>)

ويجب أن التفاف قيمة الإرجاع في مجموعة للقراءة فقط.

ومتاح من V2.0. NET

    public ArrayList MyList { get; private set; }

وجعل مجرد الممتلكات ويختم (أو NotInheritable في VB.NET) وللقراءة فقط، مثل هذا:

   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