سؤال

في المقام الأول C++ المطور غياب RAII (الموارد الاستحواذ هو التهيئة) في جافا .صافي دائما يزعجني.حقيقة أن عبء تنظيف انتقلت من الدرجة الكاتب إلى المستهلك (طريق try finally أو .صافي using بناء) يبدو بشكل ملحوظ أقل شأنا.

أرى السبب في جافا لا يوجد أي دعم RAII لأن جميع الأجسام تقع على كومة القمامة جامع بطبيعتها لا يدعم القطعية الدمار ، ولكن في .صافي مع إدخال القيمة أنواع (struct) لدينا (على ما يبدو) المرشح المثالي RAII.وهو نوع القيمة التي يتم إنشاؤها على المكدس لديه تعريف نطاق C++ المدمر دلالات يمكن استخدامها.ومع ذلك CLR لا تسمح قيمة من نوع إلى المدمر.

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

لخفض قصة قصيرة طويلة سؤالي هو:هل هناك أي أسباب أخرى أنواع قيمة لا يمكن أن تستخدم من أجل إدخال RAII إلى .الشبكة ؟ (أو هل تعتقد حجتي عن RAII هناك مزايا واضحة هي معيبة؟)

تحرير: يجب أن لا صيغت السؤال بشكل واضح منذ أول أربع إجابات قد غاب نقطة.أنا أعلم عن Finalize و غير القطعية الخصائص ، using بناء أشعر هذين الخيارين أدنى RAII. using هو واحد أكثر الشيء المستهلك من فئة يجب أن نتذكر (كم من الناس قد نسيت لوضع StreamReader في using بلوك؟).سؤالي هو فلسفي حول اللغة تصميم, لماذا هو هو و يمكن تحسينها ؟

على سبيل المثال مع عامة deterministically هالكة القيمة-النوع الأول يمكن أن تجعل من using و lock كلمات زائدة (يمكن تحقيقه عن طريق مكتبة دروس):

    public struct Disposer<T> where T : IDisposable
    {
        T val;
        public Disposer(T t) { val = t; }
        public T Value { get { return val; } }
        ~Disposer()  // Currently illegal 
        {
            if (val != default(T))
                val.Dispose();
        }
    }

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

يمكنك أن تأخذ بلدي القطعية الدمار عندما الباردة من ناحية القتلى يخرج من نطاق.--حالا

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

المحلول

عنوان أفضل أن يكون "لماذا لا يوجد RAII في C#/VB".C++/CLI (تطور الإجهاض التي كانت مدارة C++) وقد RAII في نفس المعنى مثل C++.الأمر كله مجرد جملة السكر لنفس الانتهاء نمط بقية CLI اللغات استخدام (المتلفات في إدارتها الكائنات C++/CLI بشكل فعال finalisers) ، ولكن كان هناك.

قد ترغب http://blogs.msdn.com/hsutter/archive/2004/07/31/203137.aspx

نصائح أخرى

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

براين هاري لديه لطيفة بعد عن المبررات هنا.

هنا مقتطف:

ماذا عن حتمية وضع الصيغة النهائية أنواع قيمة (البنيات)?

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

(1) تكوين - أنها لا تعطيك محددا مدى الحياة العامة ، الحالة لنفس أنواع من التكوين الأسباب المذكورة أعلاه.أي غير القطعية الطبقة التي تحتوي على واحد لن ندعو المدمر حتى تم الانتهاء من GC على أي حال.

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

دعونا نقول أننا إنشاء البنيات مع destructors لكنه أضاف مجموعة من القيود المفروضة على جعل سلوكهم معقولة في مواجهة القضايا المذكورة أعلاه.القيود سيكون شيء من هذا القبيل:

(1) يمكنك إلا أن تعلن لهم المحلي المتغيرات.

(2) يمكنك فقط تمرير لهم قبل المرجع

(3) لا يمكن التنازل عنها ، يمكن فقط الوصول إلى حقول الاتصال أساليب عليها.

(4) لا يمكنك مربع لهم.

(5) مشاكل في استخدام لهم من خلال انعكاس (الربط المتأخر) لأن ذلك عادة ما ينطوي على الملاكمة.

ربما أكثر من ذلك ، ولكن هذا هو بداية جيدة.

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

استبدال RAII في .صافي هو استخدام النمط الذي يعمل تقريبا بمجرد أن تعتاد على ذلك.

أقرب تحصل على ذلك محدودة جدا stackalloc المشغل.

هناك بعض مواضيع مشابهة إذا كنت تبحث عن لهم ولكن أساسا ما يتلخص هو أنه إذا كنت تريد أن RAII على .صافي ببساطة تنفيذ IDisposable نوع استخدام "استخدام" بيان للحصول على حتمية التخلص منها.بهذه الطريقة العديد من نفس ideoms يمكن تنفيذها واستخدامها فقط أكثر قليلا الالفاظ الطريقة.

IMHO الاشياء الكبيرة التي VB.net و C# تحتاج هي:

  1. و "باستخدام" الإعلان عن المجالات التي من شأنها أن تسبب مترجم لتوليد رمز للتخلص من جميع المجالات وبالتالي الموسومة.السلوك الافتراضي يجب أن يكون المترجم إلى جعل الطبقة تنفيذ IDisposable إذا كان لا, أو إدراج التخلص من المنطق قبل بدء الرئيسي التخلص من الروتين من أجل أي عدد من المشترك IDisposal تنفيذ أنماط أو استخدام آخر سمة النص على أن التخلص من الأشياء يجب أن تذهب في روتين مع اسم معين.
  2. وسيلة deterministically التخلص من الكائنات التي المنشئات و/أو مجال المهيآت رمي استثناء ، إما عن طريق السلوك الافتراضي (الاتصال الافتراضي طريقة التخلص من) أو مخصص السلوك (استدعاء الأسلوب مع اسم معين).
  3. بالنسبة vb.net, السيارات-إنشاء طريقة فارغة من كل WithEvent المجالات.

كل هذه يمكن أن تكون kludged بشكل جيد في vb.net و أقل إلى حد ما في C# ، ولكن من الدرجة الأولى لهم الدعم من شأنه أن يحسن اللغتين.

يمكنك القيام شكل RAII في .net و java باستخدام وضع الصيغة النهائية() الأساليب.على وضع الصيغة النهائية() الزائد يسمى قبل فئة يتم تنظيفها بواسطة GC بحيث يمكن استخدامها لتنظيف أي الموارد التي بالتأكيد لا ينبغي أن يحتفظ بها فئة (mutexes, مآخذ, ملف مقابض ، إلخ).فإنه لا يزال غير القطعية على الرغم من.

مع .صافي يمكنك القيام ببعض هذه deterministically مع واجهة IDisposable و باستخدام الكلمات الرئيسية ، ولكن هذا لا قيود (باستخدام بناء عندما تستخدم المطلوبة حتمية السلوك لا يوجد القطعية الذاكرة deallocation لا تستخدم تلقائيا في الطبقات ، إلخ).

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

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