سؤال

ومؤخرا وجدت السلوك المستغرب جدا في ج #. كان لي الطريقة التي يأخذ IEnumerable<Object> كمعلمة وأنا كان يمر IEnumerable<string> ولكن هذا غير ممكن. بينما في ج # كل شيء يمكن أن يكون موجه لأعلى لكائن من لماذا لم يكن هذا ممكنا؟ انها مربكة تماما بالنسبة لي. يرجى شخص ما واضحة لي في هذه المسألة.

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

المحلول

والمصطلح التقني لذلك هو أن الوراثة هي ثابتة في C # 3.0 والإصدارات السابقة. من C # 4.0 فصاعدا، يعمل المدلى بها.

ما هي الوسائل ثابتة هي أنه لا يوجد أي علاقة بين اثنين من الأنواع العامة لمجرد نوع عام من المعلمات ترتبط (أي هي شبه أو supertypes من بعضها البعض).

في المثال الخاص بك، ليست هناك علاقة بين الكتابة IEnumerable<object> وIEnumerable<string>، لمجرد سلسلة هو نوع فرعي من الكائن. انهم تعتبر مجرد نوعين لا علاقة لها تماما، مثل سلسلة وعدد صحيح (أنها لا تزال كلاهما فرعية من وجوه، ولكن كل شيء)

وهناك عدد قليل من الحلول والاستثناءات لهذه المشكلة التي قد واجهت.

أولا، يمكنك يلقي كل سلسلة بشكل فردي في الاعتراض، إذا كنت تستخدم Framework 3.0 يمكنك أن تفعل ذلك باستخدام طريقة تمديد Cast<T>(). خلاف ذلك، يمكنك استخدام foreach ووضع النتيجة في متغير جديد من نوع ثابت تريد.

وثانيا، صفائف استثناء لنوع مرجع، أي يمر في سلسلة [] نوع لطريقة acccepting الكائن [] يجب أن أنواع العمل.

نصائح أخرى

وكما أشار آخرون، الأدوية أنواع هي ثابتة. IEnumerable<T> يمكن أن يكون المشارك البديل ولكن C # لا يدعم حاليا متغيرات تحديد. ومن المتوقع أن تدعم المتغيرات حتى هذا قد يكون معتمدا في المستقبل C # 4.0.

لكمحاولة للتغلب على هذه الآن يمكنك استخدام Cast<object>() طريقة تمديد LINQ. بفرض أن لديك طريقة تسمى Foo التي تأخذ IEnumerable<object>>. يمكنك أن نسميها مثل هذا،

Foo(stringEnumerable.Cast<object>());

وأسهل طريقة لتمرير IEnumerable<string> على العمل تتطلب IEnumerable<object> هي من خلال تحويل وظيفة من هذا القبيل:

public IEnumerable<object> convert<T>(IEnumerable<T> enumerable)
    {
    foreach (T o in enumerable)
        yield return o;
    }

وعندما يأتي C # 4، وهذا لن يكون الضروره، لأنها سوف تدعم لاتباين وتباين مرافق وتباين معاكس.

ويجب أن تستخدم

IEnumerable<T> 

وإذا كنت تريد أن تمر في أنواع مختلفة، ثم يمكنك الاستعلام T لمعرفة ما اكتبه هو.

وهناك طريقة جيدة للتفكير في ذلك هو أن تسأل نفسك "ماذا سيحدث إذا كنت تستطيع أن تفعل هذا؟". نأخذ المثال التالي:

IEnumerable<String> strings=...;
IEnumerable<Object> objects = strings; // assume this were legal

objects.Add(new Integer(5)); // what the...

ونحن فقط واضاف عدد صحيح إلى قائمة السلاسل. المترجم يعني هذا للحفاظ على سلامة النوع.

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