كيف يمكنني معرفة ما إذا كان الصف غير قابل للتغيير في C# ؟

StackOverflow https://stackoverflow.com/questions/481909

  •  20-08-2019
  •  | 
  •  

سؤال

كيف يمكنني معرفة ما إذا كان الصف غير قابل للتغيير في C# ؟

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

المحلول

هناك ImmutableObjectAttribute, لكن هذا نادرا ما تستخدم وأيد سيئة - و بالطبع لا تنفذ (يمكنك وضع علامة قابلة للتغيير كائن [ImmutableObject(true)].AFAIK الشيء الوحيد هذا يؤثر هذا هو الطريق IDE مقابض الصفات (أيإظهار / عدم إظهار اسمه خصائص خيارات).

في الواقع, سيكون لديك للتحقق من FieldInfo.IsInitOnly, ولكن هذا ينطبق فقط على حقا 100% غير قابل للتغيير أنواع (بافتراض عدم انعكاس الاعتداء ، الخ) ؛ أنها لا تساعد مع المصاصة ثبات ولا الأشياء التي هي ثابتة في الممارسة العملية ، ولكن ليس في تنفيذها ؛ أيأنها لا يمكن أن تكون علنا قابلة للتغيير ، ولكن في نظرية الكائن يدعم ذلك.

مثال كلاسيكي هنا سيكون سلسلة...الجميع "يعرف" أن string هو غير قابل للتغيير...وبطبيعة الحال ، StringBuilder لا التحور سلسلة تحت غطاء محرك السيارة.لا بجد...

فمن الصعب جدا أن تحدد ثبات ونظرا لهذا ، ناهيك بقوة الكشف عن ذلك...

نصائح أخرى

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

class Foo
{
    public readonly int X
    public readonly int Y
    public Foo(int x, int y, Bar bar)
    {
        this.X = x; 
        bar.ShowYourself(this);
        this.Y = y;
        bar.ShowYourself(this);
    }
}

ولكن إذا كان الحقل على فئة يفترض أنها ثابتة مجموعة (وليس للقراءة فقط) ثم استدعاء الطبقة غير قابل للتغيير من المحتمل أن تكون غير صحيحة (لأنه يمكن أن الدولة تغيير)

لاحظ أنه حتى إذا كان كل الحقول يسمح انعكاس للقراءة فقط لتعديل الحقول.

والتحقق من وجود أي اضعي على العقارات سيكون الكشف عن مجريات الأمور سيئة للغاية في الواقع.

وجزء من المشكلة هو أن "ثابت" يمكن أن يكون لها معان متعددة. خذ على سبيل المثال، ReadOnlyCollection .

ونحن نميل إلى النظر أن يكون غير قابل للتغيير. ولكن ماذا لو انها ReadOnlyCollection ؟ أيضا، لأنه في الحقيقة مجرد التفاف حول وIList أمرر في منشئ، ما إذا قمت بتغيير IList الأصلي؟

قد يكون نهجا جيدا لإنشاء سمة مع اسم مثل ReadOnlyAttribute وعلامة الفئات التي تعتبر أنها للقراءة فقط معها. لفئات كنت لا تسيطر، يمكنك أيضا أن تحافظ على قائمة أنواع المعروفة التي تعتقد أنها غير قابل للتغيير.

وتحرير: بالنسبة لبعض الأمثلة الجيدة على أنواع مختلفة من ثبات، وقراءة هذه السلسلة من التعيينات من قبل اريك ليبرت: <لأ href = "http://blogs.msdn.com/ericlippert/archive/2007/11/13/immutability -في-ج-جزء واحد-أنواع-من-immutability.aspx "يختلط =" نوفولو noreferrer "> http://blogs.msdn.com/ericlippert/archive/2007/11/13/immutability-in-c- جزء واحد-أنواع-من-immutability.aspx

على حد علمي إلا إذا كان صريحا موثقة لا توجد طريقة لتحديد ما إذا كانت فئة غير قابل للتغيير أو ليس في C#.

ومع ذلك ، يمكنك استخدام انعكاس للتحقق من وجود واضعي على خصائص.ومع ذلك ، عدم وجود واضعي لا يضمن ثبات الداخلية للدولة قد تتغير قيم هذه الخصائص ما إذا كان يمكنك تعيين صراحة لهم أم لا.

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

تحرير: وهنا سؤال مماثل, طلب بخصوص لغة جافا ، الذي الإجابة أيضا ينطبق هنا.

وعن طريق الرمز، لست متأكدا، ولكن AFAIK إذا نظرتم الى IL من نوع غير قابل للتغيير آخر، مثل سلسلة صح التعبير على لا عرض لnewobj IL تعليمات (سترى ldstr سلاسل)، وربما تفقد IL الخلق قد تكون طريقة واحدة لمعرفة، مجرد تخمين ...

والمساعدة الوحيدة التي تحصل عليها من وقت التشغيل هو إذا المشروح كافة الحقول في فئة مع "للقراءة فقط". [عدل، انظرShuggyCoUk] وحتى ذلك الحين سوف CLR تمكنك من إرسال أكثر من ذلك. أنا فقط التحقق من ذلك. هتاف اشمئزاز.

ويمكنك الحصول على الكائنات FieldInfo من الطبقة عن طريق التفكير وتحقق IsInitOnly.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top