combination - enum c# شرح



كيف يلقي التعداد العام لكثافة؟ (6)

لدي طريقة صغيرة تبدو كالتالي:

public void SetOptions<T>() where T : Enum
{
    int i = 0;
    foreach (T obj in Enum.GetValues(typeof(T)))
    {
        if (i == 0)
            DefaultOption = new ListItem(obj.Description(), obj.ToString());
        i++;
        DropDownList.Items.Add(new ListItem(obj.Description(), obj.ToString()));
    }
}

أساسا ، أنا ملء قائمة المنسدلة من التعداد. Description() هو في الواقع وسيلة تمديد للتعدادات ، لذلك T بالتأكيد هو enum .

ومع ذلك ، أريد أن ألقي كلمة obj تمامًا كما تفعل أي تعداد لمؤشرها مثل هذا (int)obj ، لكني حصلت على خطأ قائلة إنه لا يمكنني تحويل T إلى int. هل هناك أي طريقة للقيام بذلك؟


أنا مندهش يعمل رمزك على الإطلاق. Enum.GetValues بإرجاع صفيف من الأعداد الصحيحة - وهي القيم التي تبحث عنها. وكما ذكر الآخرون ، لا يمكنك حصر الأدوية الخاصة بك في التعداد .

بدلاً من ذلك ، يجب عليك استدعاء طريقة Description الخاصة بك كطريقة ثابتة عادية وليس كطريقة للتمديد.


إليك طريقة أكثر بساطة.

بما أن التعداد ينفذ IConvertible يمكننا استخدام ToInt32 (..).

int? value = (enumCandidate as IConvertible)?.ToInt32(CultureInfo.InvariantCulture.Numberformat);

أو إذا كنت تريد طريقة للأغراض العامة للتعدادات العامة:

public static int GetEnumValue<T>(T inputEnum) where T: struct, IConvertible
{
    Type t = typeof(T);
    if (!t.IsEnum)
    {
        throw new ArgumentException("Input type must be an enum.");
    }

    return inputEnum.ToInt32(CultureInfo.InvariantCulture.NumberFormat);

}

أو بعد أكثر عمومية:

public static int GetEnumValue(object enumInput)
{
    Type t = enumInput.GetType();
    if (!t.IsEnum)
    {
        throw new ArgumentException("Input type must be an enum.");
    }

    return ((IConvertible)inputEnum).ToInt32(CultureInfo.InvariantCulture.NumberFormat);

}

للتوسع في إجابة جان فيما يتعلق بقيم الأدوية العامة وقيم التعداد:

void MyFunc<T>(T value)
{
    Type t = typeof(T);
    if(t.IsEnum)
    {
        int valueAsInt = value.GetHashCode(); // returns the integer value
    }
}

متأخرة قليلاً للحفلة ، لكن باستخدام Linq يمكن القيام بذلك بأناقة:

public static void SetOptions<T>(this DropDownList dropDownList)
{
    if (!typeof(T).IsEnum)
    {
        throw new ArgumentException("Type must be an enum type.");
    }

    dropDownList.Items.AddRange(Enum
        .GetValues(typeof(T))
        .Cast<Enum>()
        .Select(x => new ListItem(x.ToString(), Convert.ToInt32(x).ToString()))
        .ToArray());
}

هل يمكن أيضا أن يلقي القيمة الخاصة بك object أولا ثم إلى int .

C # 7.3 وما فوق

مع Enum العام القيد.

public static int EnumToInt<TValue>(this TValue value) where TValue : Enum
    => (int)(object)value;

أدناه C # 7.3

بدون Enum العام القيد.

public static int EnumToInt<TValue>(this TValue value)  where TValue : struct, IConvertible
{
    if(!typeof(TValue).IsEnum)
    {
        throw new ArgumentException(nameof(value));
    }

    return (int)(object)value;
}

إذا كان التعداد الخاص بك يرث من أنواع أخرى على سبيل المثال من byte فإن فريق Cast to int سوف يرمي InvalidCastException .

يمكنك التحقق مما إذا كان النوع الأساسي للتعداد هو عدد صحيح.

public static int EnumToInt<TValue>(this TValue value) where TValue : Enum
{
    if (!typeof(int).IsAssignableFrom(Enum.GetUnderlyingType(typeof(TValue))))
        throw new ArgumentException(nameof(TValue));

    return (int)(object)value;
}

أو إذا كنت تستخدم Convert.ToInt32 ، فسوف تستخدم واجهة IConvertible لـ int32 لتحويل الأنواع غير المتوافقة.

public static int EnumToInt<TValue>(this TValue value) where TValue : Enum
    => Convert.ToInt32(value);

فقط كن على دراية بأن تحويل uint إلى int و الأزواج الموقعة / غير الموقعة يمكن أن يسبب سلوك غير مقصود. (الملاكمة إلى IConvertible والتحويل هو أقل أداء من مجرد unboxing.)

أوصي بإنشاء طريقة لكل نوع قاعدة التعداد لضمان إرجاع النتيجة الصحيحة.


يمكنك إساءة GetHashCode لهذا؟

public enum MyEnum
{
  Foo = 100,
  Bar = 200,
  Fizz = 0
}

static void Main(string[] args)
{
  var i1 = MyEnum.Foo.GetHashCode();  // i1 = 100
  var i2 = MyEnum.Bar.GetHashCode();  // i2 = 200
  var i3 = MyEnum.Fizz.GetHashCode(); // i3 = 0
}

يرجى ملاحظة: " GetHashCode() هو حسب التصميم مفيد لشيء واحد فقط: وضع كائن في جدول التجزئة. ومن ثم الاسم." - إي ليبيرت





enums