سؤال

ملحوظة:تم نشر هذا عندما كنت أبدأ باستخدام لغة C#.بفضل معرفتي بعام 2014، أستطيع أن أقول حقًا أن الخصائص التلقائية هي من بين أفضل الأشياء التي حدثت للغة C# على الإطلاق.

أنا معتاد على إنشاء خصائصي في C# باستخدام حقل خاص وعام:

private string title;
public string Title
{
    get { return title;  }
    set { title = value;  }
}

الان مع .شبكة 3.0، حصلنا على خصائص تلقائية:

public string Title { get; set; }

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

في الواقع، لا يظهر الحقل الخاص المخفي في مصحح الأخطاء، وهو أمر جيد نظرًا لأن وظائف get/set لا تفعل شيئًا.ولكن عندما أرغب في تنفيذ بعض منطق getter/setter، لا بد لي من استخدام الزوج الخاص/العام على أي حال.

أرى فائدة حفظ الكثير من التعليمات البرمجية (أسطر واحد مقابل ستة أسطر) دون فقدان القدرة على تغيير منطق getter/setter لاحقًا، ولكن مرة أخرى يمكنني فعل ذلك بالفعل عن طريق الإعلان عن حقل عام "عنوان سلسلة عامة" بدون الحاجة إلى { get؛تعيين؛}، وبالتالي توفير المزيد من التعليمات البرمجية.

إذن، ما الذي أفتقده هنا؟لماذا يريد أي شخص بالفعل استخدام الخصائص التلقائية؟

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

المحلول

نحن نستخدمها طوال الوقت في Stack Overflow.

قد تكون مهتمًا أيضًا بمناقشة خصائص مقابل.المتغيرات العامة.IMHO هذا حقًا ما يعد رد فعل عليه، ولهذا الغرض، إنه أمر رائع.

نصائح أخرى

نعم إنها كذلك فقط حفظ الرمز.من الأسهل قراءتها عندما يكون لديك الكثير منها.إنها أسرع في الكتابة وأسهل في الصيانة.يعد حفظ الكود دائمًا هدفًا جيدًا.

يمكنك تعيين نطاقات مختلفة:

public string PropertyName { get; private set; }

بحيث لا يمكن تغيير الخاصية إلا داخل الفصل.هذا ليس غير قابل للتغيير حقًا حيث لا يزال بإمكانك الوصول إلى أداة الضبط الخاصة من خلال التفكير.

اعتبارًا من C#6، يمكنك أيضًا إنشاء صحيح readonly الخصائص - أيالخصائص الثابتة التي لا يمكن تغييرها خارج المنشئ:

public string PropertyName { get; }

public MyClass() { this.PropertyName = "whatever"; }

في وقت الترجمة الذي سيصبح:

readonly string pName;
public string PropertyName { get { return this.pName; } }

public MyClass() { this.pName = "whatever"; }

في الفصول غير القابلة للتغيير التي تضم الكثير من الأعضاء، يوفر هذا الكثير من التعليمات البرمجية الزائدة.

الجوانب السلبية الثلاثة الكبيرة لاستخدام الحقول بدلاً من الخصائص هي:

  1. لا يمكنك ربط البيانات بحقل بينما يمكنك ربطه بخاصية
  2. إذا بدأت باستخدام حقل، فلن تتمكن لاحقًا (بسهولة) من تغييره إلى خاصية
  3. هناك بعض السمات التي يمكنك إضافتها إلى خاصية لا يمكنك إضافتها إلى الحقل

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

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

تسمح لك الخصائص أيضًا بتعيين مستويات وصول مختلفة لـ getter وsetter وهو ما لا يمكنك فعله باستخدام الحقل.

أعتقد أنها نفس الكلمة الأساسية var.مسألة تفضيل شخصي.

من بيارن ستروستروب، مبتكر لغة C++:

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

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

شيء واحد يبدو أنه لم يذكره أحد هو كيف أن الخصائص التلقائية ليست مفيدة للأسف للكائنات غير القابلة للتغيير (عادةً ما تكون بنيات غير قابلة للتغيير).لأنه من أجل ذلك يجب عليك فعل ما يلي:

private readonly string title;
public string Title
{
    get { return this.title; }
}

(حيث تتم تهيئة الحقل في المنشئ عبر معلمة تم تمريرها، ثم تتم قراءته فقط.)

لذلك فإن هذا له مزايا أكثر من البساطة get/private set com.autoproperty.

أقوم دائمًا بإنشاء خصائص بدلاً من الحقول العامة لأنه يمكنك استخدام الخصائص في تعريف الواجهة، ولا يمكنك استخدام الحقول العامة في تعريف الواجهة.

تعد الخصائص التلقائية بمثابة سحر أسود مثل أي شيء آخر في لغة C#.بمجرد التفكير في الأمر من حيث التجميع إلى IL بدلاً من توسيعه إلى خاصية C# عادية أولاً، فهو أقل سحرًا أسود بكثير من الكثير من بنيات اللغة الأخرى.

أستخدم الخصائص التلقائية طوال الوقت.قبل C#3، لم أكن منزعجًا من كل أنواع الكتابة واستخدمت المتغيرات العامة بدلاً من ذلك.

الشيء الوحيد الذي أفتقده هو القدرة على القيام بذلك:

public string Name = "DefaultName";

يجب عليك تحويل الإعدادات الافتراضية إلى المنشئات الخاصة بك باستخدام الخصائص.مضجر :-(

أعتقد أن أي بناء بديهي ويقلل من سطور التعليمات البرمجية يعد ميزة إضافية كبيرة.

هذه الأنواع من الميزات هي ما يجعل لغات مثل Ruby قوية للغاية (وهذا بالإضافة إلى الميزات الديناميكية التي تساعد أيضًا في تقليل التعليمات البرمجية الزائدة).

لقد واجهت روبي هذا طوال الوقت على النحو التالي:

attr_accessor :my_property
attr_reader :my_getter
attr_writer :my_setter

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

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

بهذه البساطة.

هناك شيء واحد يجب ملاحظته هنا، وهو ما أفهمه فقط السكر النحوي في نهاية C# 3.0، مما يعني أن IL الذي تم إنشاؤه بواسطة المترجم هو نفسه.أوافق على تجنب السحر الأسود، ولكن مع ذلك، عادةً ما يكون عدد أقل من الأسطر لنفس الشيء أمرًا جيدًا.

في رأيي، يجب عليك دائمًا استخدام الخصائص التلقائية بدلاً من الحقول العامة.ومع ذلك، وهنا حل وسط:

ابدأ بـ داخلي الحقل باستخدام اصطلاح التسمية الذي ستستخدمه للخاصية.عندما تكون أولًا أيضًا

  • بحاجة إلى الوصول إلى الميدان من خارج التجمع، أو
  • تحتاج إلى إرفاق المنطق إلى getter/setter

افعل هذا:

  1. إعادة تسمية الحقل
  2. اجعلها خاصة
  3. إضافة ملكية عامة

لن يحتاج رمز العميل الخاص بك إلى التغيير.

ومع ذلك، يومًا ما، سينمو نظامك وستقوم بتفكيكه إلى مجموعات منفصلة وحلول متعددة.عندما يحدث ذلك، فإن أي حقول مكشوفة ستعود لتطاردك لأنه، كما ذكر جيف، يعد تغيير حقل عام إلى ملكية عامة تغييرًا جذريًا في واجهة برمجة التطبيقات (API)..

أستخدم CodeRush، وهو أسرع من الخصائص التلقائية.

لفعل هذا:

 private string title;
public string Title
{
    get { return title;  }
    set { title = value;  }
}

يتطلب إجمالي ثماني ضغطات على المفاتيح.

حسنًا، مع مقتطفات التعليمات البرمجية، ستكون الخاصية التلقائية التي تحمل الاسم نفسه سبع ضغطات على المفاتيح إجمالاً؛)

@ دومينيك :انا لم احصل عليها..لا يمكنك القيام بذلك باستخدام الخصائص التلقائية ؟:

public string Title { get; }

أو

public string Title { get; private set; }

هل هذا ما تشير اليه؟

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

ما يفتقده VS2008 هو ملف تنفجر الملكية التلقائية إعادة بناء.

حقيقة لدينا تغليف المجال refactor يجعل الطريقة التي أعمل بها أسرع من خلال استخدام الحقول العامة فقط.

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