تعيين نوع إلى المتغير، واستخدام المتغير مع فئة ثابتة عام

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

سؤال

أنا أعمل في خدمة الويب C # مع فئة ثابتة عامة تأخذ نوعا. كنت أتساءل لماذا هذا لا يترجم:

Type type1 = typeof(MySnazzyType);
Assert.AreEqual(0, ConnectionPool_Accessor<type1>._pool.Count);

إنه يعطي هذا الخطأ:

لا يمكن العثور على اسم نوع أو اسم الاسم "Type1" (هل تفتقد استخدام التوجيه أو مرجع التجميع؟)

وإعادة التجسيد، عندما أحرز type1 في هذا السطر الثاني من التعليمات البرمجية، يقول "نوع أو اسم اسم الاسم المتوقع". نحن سوف، type1 هو نوع! إنه متغير من النوع Typeفي كما أنه لا يعمل إذا فعلت:

Type type1 = typeof(MySnazzyType);
Assert.AreEqual(0, ConnectionPool_Accessor<typeof(type1)>._pool.Count);

كنت آمل في تعيين أنواعي إلى بضع مختلف Type المتغيرات واستخدم فقط أولئك الذين يختبرون الطبقات الثابتة العامة المختلفة، بدلا من الكتابة MySnazzyType كل مرة. أي أفكار، أو أنا عالقة مع القيام به:

Assert.AreEqual(0, ConnectionPool_Accessor<MySnazzyType>._pool.Count);

تعديل: للتوضيح، MySnazzyType هو ليس فئة عامة، ولا ترث من فئة عامة. الطبقة العامة الوحيدة هنا هي ConnectionPool_Accessor.

بفضل تعليق بافيل "أساسا، مشكلتك هي أن C # هي لغة مكتوبة ثابتة"، وأنا أعلم الآن أن Ruby قد أفسدني. ؛)

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

المحلول

بادئ ذي بدء، resharper هو في الواقع صحيح. هذا ليس أ يكتب, ، انه عامل. وبعد منحها، إنه متغير يحمل كائن الانعكاس الذي يتوافق مع نوع، ولكن هذا ليس كافيا.

بين <...> قوسين، عليك كتابة اسم النوع، وليس اسم أي معرف آخر.

يمكنك بناء كائنات عامة من خلال التفكير، ومع ذلك، والوصول إلى خصائصها، حتى منها ثابتة، لذلك يجب أن تكون قادرا على إعادة كتابة التعليمات البرمجية للقيام بذلك، ومع ذلك، هل نظرت إلى Nunit 2.5؟

من أحدث ملاحظات الإصدار، يبدو أن فئات اختبار الوحدات يمكن أن تكون الآن عام، ويمكنك تحديد سمة في فئة الاختبار التي يمكن أن تختبرها معها.

هذا من شأنه أن يسمح لك بكتابة شيء من هذا القبيل (ملاحظة، لم أختبر ذلك، نظرت فقط بأسماء السمات الجديدة في الوثائق):

[TestFixture(typeof(MySnazzyType))]
[TestFixture(typeof(MyOtherSnazzyType))]
public class Tests<T>
{
    [Test]
    public void PoolCount_IsZero()
    {
        Assert.AreEqual(0, ConnectionPool_Accessor<T>._pool.Count);
    }
}

نصائح أخرى

يتم تقييم أنواع عامة في وقت الترجمة, ، ليس في مدة العرض. وبعد لأنه لا يمكن تحديده في وقت وقت التشغيل ما type1 سيكون، هذا البناء غير مسموح به.

هذا هو في الواقع ما يقوله resharper: type1 ليس نوعا، إنه متغير من النوع Type, ، (تماما كما يمكن أن يكون كائن من النوع String).

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

Type poolType = typeof(ConnectionPool_Accessor<>);
Type snazzyType = typeof(MySnazzyType); // Or however you want to get the appropriate Type
poolType.MakeGenericType(snazzyType);

يمكنك بعد ذلك المتابعة للقيام بكل ما تريد استخدام انعكاس poolType. وبعد بالطبع، سيكون ذلك ألم كبير في بعقب ما لم تستخدم الكتابة الديناميكية C # 4.0.

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