سؤال

لدي مشكلة مع التعداد

أحتاج إلى إنشاء تعداد في الفئة الأساسية أو الواجهة (لكن واحدة فارغة)

class Base 
{
   public enum Test;
   // ???
}

وبعد إجراء تعدادات مختلفة في بعض الفئات الأصلية

class Parent1
{
   public enum Test {A, B, C};
}

class Parent2
{
   public enum Test {J, H, K};
}

والآن لدي الفصل التالي بالطريقة عندما يتعين علي استخدام التعداد

class Test<T>
{
   public void Foo(Test enum)
   {
      int value = (int) enum;
      // ...
   }
}

هل هناك أي طريقة لفعل شيء من هذا القبيل؟

إذا لم يكن الأمر كذلك فلا بد لي من استخدام ints الثابتة في كل فصل ...

class Parent1
{
   public static int A = 0;
   public static int B = 5;
   public static int C = 7;
}

class Parent2
{
   public static int J = 1;
   public static int H = 3;
   public static int K = 6;
}

class Test<T>
{
   public void Foo(int enum)
   {
      int value = enum;
      // ...
   }
}

لا أبدو سيئًا في الكود...في بعض الفصول لا بد لي من استخدام ~ 20+ متغيرات

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

المحلول

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

class Base<T> where T : struct {
    private T value;
    public void Foo(T value) {
        this.value = value;
    }
}
class Parent1 : Base<Parent1.Enum1> {
    public enum Enum1 {A, B, C};
}
class Parent2 : Base<Parent2.Enum2> {
    public enum Enum2 { J, H, K };
}

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

static Base() {
    if (!typeof(T).IsEnum) throw new InvalidOperationException(
         typeof(T).Name + " is not an enum");
}

نصائح أخرى

وإنه لأمر مدهش كيف غالبا ما أجد الناس يتجادلون حول <م> لماذا مطلوب شيئا، بدلا من الإجابة على السؤال طلب أو حفظ schtum - إما من شأنها أن تكون أكثر فائدة من إضاعة الوقت استجواب <م> لماذا تم إجراء تحقيق معين في الأفضلية لتحقيق مختلف المدعى يعرف في الواقع الإجابة على. الإجابة على الأسئلة التي لم يتم طرحه هو في أي وسيلة مفيدة، OK الرجال ؟!

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

    public enum WebControlTextBoxProperties { }

    public enum WebControlLabelProperties { }

... وهلم جرا.

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

وأتمنى حقا كان هذا ممكنا في C # كما هو الحال في VB، لأنها تريد ان تكون ميزة مفيدة حقا.

ويجب أن تكون قادرة على الإعلان عن التعداد في فئة أساسية ثم تغيير القيم في أي بمعنى فئة مشتقة.

class MyClass
{
    public enum TestEnum { }

    public MyClass()
    {
    }
}

class MyDerivedClass
{
    public enum TestEnum { value1, value2, value3 }

    public MyDerivedClass()
    {
    }
}

والطبقة MyDervied سيكون الوصول إلى TestEnum.value1، TestEnum.value2، TestEnum.value3، حيث كما سيكون MyClass فقط الوصول إلى نوع.

ولكن، أنا شخصيا لا أرى ميزة للقيام بذلك وأود أن أعلن ALL قيم التعداد في الفئة الأساسية وفقط استخدام تلك أحتاج في الصف الواحد.

وجيمس.

لا، لا يمكن القيام به.

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

لا، لا توجد وسيلة لفرض أي شيء ثابت في واجهة.

وربما تحتاج إلى إعادة النظر في التصميم الخاص بك.

لماذا أنت غير قادر على تحديد التعداد في الفئة الأساسية:

class Base 
{
   public enum Test {A, B, C, J, H, K};
}

واستخدام فقط الأعضاء المعنيين من التعداد في الفئات المشتقة؟

وأنا في العمل بحيث لا يمكن وضع تماما، ولكن هذا ممكن إلى حد ما. الجانب السلبي إلى رمز أدناه لا يمكنك سلسلة تتضمن التعدادات معا، مثل TextBoxProperties، وMyCustomTextBoxProperties: TextboxProperties

وهنا هو رمز.

    public enum Test
    {

    }

    public enum ThisTest
    {
        MyVal1,
        MyVal2,
        MyVal3
    }

    public abstract class MyBase
    {
        public Test MyEnum { get; set; }
    }

    public class MyDerived : MyBase
    {
        public new ThisTest MyEnum { get; set; }
    }

أنت يستطيع ملخص التعداد!

لماذا يصر الناس على الادعاء بأن الأمور مستحيلة دون التحقق من أي شيء؟

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

على سبيل المثال:

        // abstracted enumeration value
        Enum abstractEnum = null;

        // set to the Console-Color enumeration value "Blue";
        abstractEnum = System.ConsoleColor.Blue;

        // the defined value of "ConsoleColor.Blue" is "9":
        // you can get the value via the ToObject method:
        Console.WriteLine((int)Enum.ToObject(abstractEnum.GetType(), abstractEnum));

        // or via the GetHashCode() method:
        Console.WriteLine(abstractEnum.GetHashCode());

        // the name can also be acessed:
        Console.WriteLine(Enum.GetName(abstractEnum.GetType(), abstractEnum));

الإخراج من الكود أعلاه:

9

9

أزرق

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

if ( !typeof(T).IsEnum || typeof(int) != Enum.GetUnderlyingType(typeof(T)) )
{
     throw new InvalidOperationException( typeof(T).Name + " is not an enum");
}

وهنا الحل الذي يعمل بالنسبة لي:

وفي الفئة الأصل، أن يعلن أرض الملعب كثافة العمليات، وليس كما التعداد:

protected int state;

وهكذا الفئة الأصل يمكن الاستمرار في استخدام هذه القيمة بوصفها كثافة العمليات، من أجل توفير التسلسل وdeserializion من هذه القيمة إلى القرص.

وبعد ذلك، الذي يتجاوز الفئة يمكن القيام بذلك:

enum states{
  state1, state2
}

this.state = state1.toInt();

ويمكن الوصول إلى القيمة الفعلية مثل هذا:

...
if (this.state == states.state1.toInt()){
      ...
}
else{
     ...
}

وحيث يتم تعريف toInt () في فئة ثابتة كما يلي:

public static class Utils
{

    public static int toInt(this state s)
    {
        return (int)s;
    }
 }
scroll top