سؤال

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

كما أنه ينتهي الدعوة Convert.ChangeType الذي فشل مع غير صالح يلقي استثناء.

وجدت ما كنت تنظر رائحة كريهة الحل, مثل هذا:

String name = Enum.GetName(destinationType, value);
Object enumValue = Enum.Parse(destinationType, name, false);

هل هناك طريقة أفضل, بحيث لا تضطر إلى التحرك من خلال هذه السلسلة العملية ؟

وهنا القصير ، ولكن كاملة, البرامج التي يمكن استخدامها إذا كان أي شخص في حاجة إلى التجربة:

using System;

public class MyClass
{
    public enum DummyEnum
    {
        Value0,
        Value1
    }

    public static void Main()
    {
        Int16 value = 1;
        Type destinationType = typeof(DummyEnum);

        String name = Enum.GetName(destinationType, value);
        Object enumValue = Enum.Parse(destinationType, name, false);

        Console.WriteLine("" + value + " = " + enumValue);
    }
}
هل كانت مفيدة؟

المحلول

Enum.ToObject(.... هو ما كنت تبحث عنه!

C#

StringComparison enumValue = (StringComparison)Enum.ToObject(typeof(StringComparison), 5);

VB.NET

Dim enumValue As StringComparison = CType([Enum].ToObject(GetType(StringComparison), 5), StringComparison)

إذا كنت تفعل الكثير من التعداد تحويل حاول استخدام الطبقة التالية سيوفر لك الكثير من التعليمات البرمجية.

public class Enum<EnumType> where EnumType : struct, IConvertible
{

    /// <summary>
    /// Retrieves an array of the values of the constants in a specified enumeration.
    /// </summary>
    /// <returns></returns>
    /// <remarks></remarks>
    public static EnumType[] GetValues()
    {
        return (EnumType[])Enum.GetValues(typeof(EnumType));
    }

    /// <summary>
    /// Converts the string representation of the name or numeric value of one or more enumerated constants to an equivalent enumerated object.
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    /// <remarks></remarks>
    public static EnumType Parse(string name)
    {
        return (EnumType)Enum.Parse(typeof(EnumType), name);
    }

    /// <summary>
    /// Converts the string representation of the name or numeric value of one or more enumerated constants to an equivalent enumerated object.
    /// </summary>
    /// <param name="name"></param>
    /// <param name="ignoreCase"></param>
    /// <returns></returns>
    /// <remarks></remarks>
    public static EnumType Parse(string name, bool ignoreCase)
    {
        return (EnumType)Enum.Parse(typeof(EnumType), name, ignoreCase);
    }

    /// <summary>
    /// Converts the specified object with an integer value to an enumeration member.
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    /// <remarks></remarks>
    public static EnumType ToObject(object value)
    {
        return (EnumType)Enum.ToObject(typeof(EnumType), value);
    }
}

الآن بدلا من الكتابة (StringComparison)Enum.ToObject(typeof(StringComparison), 5); يمكنك ببساطة كتابة Enum<StringComparison>.ToObject(5);.

نصائح أخرى

واستنادا إلى @ الجواب بطرس هنا هو طريقة لNullable<int> إلى Enum التحويل:

public static class EnumUtils
{
        public static bool TryParse<TEnum>(int? value, out TEnum result)
            where TEnum: struct, IConvertible
        {
            if(!value.HasValue || !Enum.IsDefined(typeof(TEnum), value)){
                result = default(TEnum);
                return false;
            }
            result = (TEnum)Enum.ToObject(typeof(TEnum), value);
            return true;
        }
}

وعن طريق EnumUtils.TryParse<YourEnumType>(someNumber, out result) يصبح مفيدا للعديد من السيناريوهات. على سبيل المثال، WebApi تحكم في Asp.NET لم يكن لديك الحماية الافتراضية ضد بارامس التعداد غير صالحة. سوف Asp.NET مجرد استخدام قيمة default(YourEnumType)، حتى لو null بعض الممرات، -1000، 500000، "garbage string" أو تتجاهل تماما المعلمة. وعلاوة على ذلك، سوف ModelState تكون صالحة في جميع هذه الحالات، حتى واحد من الحل هو استخدام نوع int? مع الاختيار مخصصة

public class MyApiController: Controller
{
    [HttpGet]
    public IActionResult Get(int? myEnumParam){    
        MyEnumType myEnumParamParsed;
        if(!EnumUtils.TryParse<MyEnumType>(myEnumParam, out myEnumParamParsed)){
            return BadRequest($"Error: parameter '{nameof(myEnumParam)}' is not specified or incorrect");
        }      

        return this.Get(washingServiceTypeParsed);            
    }
    private IActionResult Get(MyEnumType myEnumParam){ 
       // here we can guarantee that myEnumParam is valid
    }

إذا كنت تخزين والتعداد في DataTable ولكن لا أعرف أي عمود هو التعداد والتي هي عبارة عن سلسلة / الباحث، يمكنك الوصول إلى قيمة هذه الطريقة:

foreach (DataRow dataRow in myDataTable.Rows)
{
    Trace.WriteLine("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
    foreach (DataColumn dataCol in myDataTable.Columns)
    {
        object v = dataRow[dataCol];
        Type t = dataCol.DataType;
        bool e = false;
        if (t.IsEnum) e = true;

        Trace.WriteLine((dataCol.ColumnName + ":").PadRight(30) +
            (e ? Enum.ToObject(t, v) : v));
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top