تحويل الهياكل بشكل أعمى إلى فئات لإخفاء المُنشئ الافتراضي؟

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

سؤال

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

الحل الواضح هو مجرد تحويل struct إلى class والتعامل مع العواقب.

هل هناك خيارات أخرى للحفاظ عليها ك struct?

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

اعتقدت أننا إذا كنا سنبقي الكائن ك struct, ، يجب تقديم آلية للتحقق من صحة الدولة (شيء مثل IsValid منشأه). لقد قابلت الكثير من المقاومة ، وشرح "من يستخدم واجهة برمجة التطبيقات لا ينبغي أن يستخدم المُنشئ الافتراضي" ، وهو تعليق أثار حاجبي بالتأكيد. (ملاحظة: يتم إنشاء الكائن المعني "بشكل صحيح" من خلال طرق المصنع الثابت ، وجميع المنشئين الآخرين internal.)

هل الجميع ببساطة يحولونهم structق classES في هذه الحالة دون التفكير الثاني؟

تحرير: أود أن أرى بعض الاقتراحات حول كيفية الحفاظ على هذا النوع من الكائنات كملف struct - الكائن المذكور أعلاه أكثر ملاءمة على أنه أ struct من ك class.

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

المحلول

ل struct, ، يمكنك تصميم النوع بحيث يكون المثيل الافتراضي الذي تم إنشاؤه (الحقول All Zero) حالة صالحة. لم تكن [لا يجوز] استخدام تعسفي struct بدلاً من class بدون سبب وجيه - لا حرج في استخدام نوع مرجعي ثابت.

اقتراحاتي:

  • تأكد من سبب استخدام أ struct هو صالح (كشف [حقيقي] البروفيلر عن مشاكل كبيرة في الأداء الناتجة عن التخصيص الثقيل لكائن خفيف الوزن للغاية).
  • صمم النوع بحيث يكون المثيل الافتراضي الصحيح صالحًا.
  • إذا تم إملاء تصميم النوع بواسطة قيود interop native/com ، لف الوظائف ولا تعرض struct خارج الغلاف (النوع المتداخل الخاص). وبهذه الطريقة يمكنك بسهولة توثيق والتحقق من الاستخدام السليم لمتطلبات النوع المقيد.

نصائح أخرى

والسبب في ذلك هو أن البنية (مثيل للنظام. أنت لا تحتاج حقًا إلى إنشاء واحدة - فقط أعلن ذلك. هذا هو السبب في حاجة المُنشرين الافتراضيين.

يمكنك الالتفاف على هذا بطريقتين:

  1. قم بإنشاء خاصية مثل IsValid للإشارة إلى ما إذا كانت بنية صالحة ، كما تشير و
  2. في .NET 2.0 النظر في استخدام Nullableu003CT> للسماح بنية (خالية) غير مهيأة.

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

يتم توضيح السبب في عدم وجود إمكانية لتحديد مُنشئ افتراضي من خلال التعبير التالي:

new MyStruct[1000];

لديك 3 خيارات هنا

  1. استدعاء المنشئ الافتراضي 1000 مرة ، أو
  2. إنشاء بيانات تالفة (لاحظ أن البنية يمكن أن تحتوي على مراجع ؛ إذا لم تقم بتهيئة أو تفريغ المرجع ، فيمكنك الوصول إلى ذاكرة تعسفية) أو
  3. قم بتفريغ الذاكرة المخصصة بالأصفار (على مستوى البايت).

.NET يفعل نفس الشيء لكل من الهياكل والفئات: الحقول وعناصر الصفيف معروضة بالأصفار. هذا أيضًا يحصل على سلوك أكثر اتساقًا بين الهياكل والفئات وعدم وجود رمز غير آمن. كما يسمح لإطار .NET بعدم التخصص في شيء ما new byte[1000].

وهذا هو المُنشئ الافتراضي للهياكل. NET يتطلب ويعتني بنفسه: صفر خارج جميع البايتات.

الآن ، للتعامل مع هذا ، لديك خياران:

  • أضف خاصية AM-I-Initialized إلى الهيكل (مثل HasValue على Nullable).
  • السماح للبنيس الصفر أن يكون قيمة صالحة (مثل 0 قيمة صالحة لعشرية).
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top