سؤال

ممكن مكررة:
لماذا قابلة للتغيير البنيات الشر ؟

قرأت في الكثير من الأماكن بما في ذلك هنا أنه من الأفضل جعل البنيات ثابتة لا تقبل التغيير.

ما هو السبب وراء هذا ؟ أرى الكثير من Microsoft إنشاء البنيات التي هي قابلة للتغيير, مثل تلك التي في xna.ربما هناك العديد من المزيد في القسم.

ما هي إيجابيات وسلبيات لا تتبع هذا المبدأ التوجيهي ؟

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

المحلول

يجب أن تمثل البنيات القيم.القيم لا تتغير.العدد 12 هو الأبدية.

ومع ذلك ، ينظر:

Foo foo = new Foo(); // a mutable struct
foo.Bar = 27;
Foo foo2 = foo;
foo2.Bar = 55;

الآن فو.شريط foo2.شريط مختلفة ، والتي غالبا ما تكون غير متوقعة.وخاصة في سيناريوهات مثل خصائص (لحسن الحظ مترجم الكشف عن هذا).ولكن أيضا مجموعات إلخ ؛ كيف من أي وقت مضى التحور لهم بعقلانية ؟

فقدان البيانات من السهل جدا الآن مع قابلة للتغيير البنيات.

نصائح أخرى

كبيرة كون أن الأمور لا تتصرف كيف تتوقع منهم - لا سيما إذا كان التغير يأتي من خليط المباشر قيمة و نوع مرجع في ذلك.

أن نكون صادقين, أنا لا أتذكر من أعلى رأسي كل المشاكل الغريبة رأيت الناس تأتي في مجموعات الأخبار عندما كنت تستخدم قابلة للتغيير البنيات - ولكن هذه الأسباب موجودة بالتأكيد. قابلة للتغيير البنيات يسبب مشاكل. البقاء بعيدا.

تحرير:لقد وجدت رسالة بريد إلكتروني كتبت قبل فترة في هذا الموضوع.وهو يضع قليلا:

  • إنه فلسفيا الخطأ:البنية يجب أن تمثل نوعا من القيمة الأساسية.تلك هي أساسا غير قابل للتغيير.لا يمكنك تغيير عدد 5.يمكنك تغيير متغير قيمة من 5 إلى 6 ، ولكن لم يكن منطقيا إجراء تغيير على القيمة نفسها.

  • انها عمليا المشكلة:فإنه يخلق الكثير من حالات غريبة.انها سيئة لا سيما إذا كانت قابلة للتغيير عبر واجهة.ثم يمكنك البدء في تغيير محاصر القيم.Ick.لقد رأيت الكثير من أخبار الوظائف التي من المقرر أن الناس يحاولون استخدام قابلة للتغيير البنيات و الوقوع في القضايا.رأيت غريبة جدا LINQ سبيل المثال والتي كان الفشل بسبب List<T>.Enumerator هو البنية ، على سبيل المثال.

يمكنني استخدام قابلة للتغيير البنيات في كثير من الأحيان في (الأداء الحرجة) مشروع - و لا تشغيل في مشاكل لأني فهم الآثار المترتبة على نسخ دلالات.بقدر ما أستطيع أن أقول, السبب الرئيسي الناس داعية ثابتة البنيات حتى أن الناس الذين لا فهم آثار لا يمكن الحصول على أنفسهم في ورطة.

هذا ليس مثل هذا شيء فظيع ولكن نحن الآن في خطر من أن تصبح "الحقيقة المطلقة" ، في حين أن هناك أوقات حيث شرعيا أفضل خيار لجعل البنية قابلة للتغيير.مثل كل الأشياء هناك استثناءات لهذه القاعدة.

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

للأسف قابلة للتغيير البنيات لا تلعب بشكل جيد مع الكائنات والخصائص ، هو الطريق السهل جدا لتعديل نسخة من stuct بدلا من البنية نفسها.وبالتالي فإنها لا تناسب معظم التعليمات البرمجية الخاصة بك.

P. S.لتجنب تكلفة نسخ قابلة للتغيير البنيات ، فهي عادة ما تكون مخزنة ومرت في المصفوفات.

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

public void DoSomething(MySomething something)
{
    something.Property = 10;
}

يتصرف بشكل مختلف تماما اعتمادا على إذا MySomething هو struct أو class.بالنسبة لي هذا هو مقنعة, ولكن ليس السبب الأكثر إلحاحا.إذا نظرتم DDD's قيمة الكائن, يمكنك رؤية اتصال كيف البنيات ينبغي أن يعامل.قيمة الكائن في DDD يمكن أن يكون أفضل ممثلة نوع قيمة في .صافي (وبالتالي البنية).لأنه لا يوجد لديه هوية, لا يمكن أن تتغير.

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

كنت قد طلبت إيجابيات وسلبيات لا بعد التوجيهي البنيات يجب أن تكون ثابتة.

سلبيات: سلبيات مغطاة جيدا في القائمة إجابات معظم المشكلات الموضحة هي بسبب نفس السبب سلوك غير متوقع بسبب البنيات قيمة دلالات.

الايجابيات: المؤيد الرئيسي من استخدام قابلة للتغيير البنيات يمكن الأداء.ومن الواضح أن هذه النصيحة تأتي مع جميع التحذيرات المعتادة حول أمثلية:تأكد من أن جزء من التعليمات البرمجية الخاصة بك يحتاج أن يكون الأمثل والتأكد من أي تغييرات فعلا تحسين التعليمات البرمجية الخاصة بك أداء طريق التنميط.

ممتازة المادة مناقشة عندما قد ترغب في استخدام قابلة للتغيير البنيات ، انظر ريكو مارياني الأداء مسابقة على قيمة البرمجة على أساس (أو بشكل أكثر تحديدا ، الإجابات).

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

دلالات يحصل على أبسط عند استخدام ثابتة البنيات ، يمكنك تجنب المزالق مثل هذا:

// a struct
struct Interval {
   int From { get; set; }
   int To { get; set; }
}

// create a list of structs
List<Interval> intervals = new List<Interval>();

// add a struct to the list
intervals.Add(new Interval());

// try to set the values of the struct
intervals[0].From = 10;
intervals[0].To = 20;

والنتيجة هي أن البنية في قائمة لا تتغير على الإطلاق.التعبير الفترة[0] نسخة قيمة البنية من القائمة ، ثم تغيير الخاصية قيمة مؤقتة ، ولكن القيمة لم يضع مرة أخرى في القائمة.

تحرير:غيرت سبيل المثال استخدام قائمة بدلا من صفيف.

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

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

حدث لي مرة أخرى الأسبوع الماضي, تبقى لي ساعة من البحث عن الخلل.

الحفاظ على البنيات الثابتة يمنع ذلك ...

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

السبب في أن جعل البنيات الثابتة هو انهم ValueTypes, بمعنى أن يتم نسخها في كل مرة كنت تمر بها الأسلوب.

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

إذا كنت التصميم الخاص بك البنيات من أجل ثبات ، التي تساعد المبرمج تجنب هذه الأخطاء.

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