"قراءة فقط" ثانوي العقارات في C #
-
03-07-2019 - |
سؤال
ولدي الطبقة التالية:
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 وبالتالي فإن المستخدم سوف لا يزال قادرا على ترجمة مع. إضافة كنها شأنه أن يؤدي إلى خطأ وقت التشغيل.
نصائح أخرى
public IEnumerable MyList
{
get { return ArrayList.ReadOnly(mMyList); }
}
<اقتباس فقرة>
ومجموعة الذي هو للقراءة فقط مجرد جمع مع مجمع يمنع تعديل مجموعة. إذا تم إجراء تغييرات على جمع الأساسي، للقراءة فقط جمع يعكس هذه التغييرات.
وهذه الطريقة هو O (1) العملية.
اقتباس فقرة> وفقط للتوسع في الجواب 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();
}