ProgramingTip

Convert.ChangeType 및 열거 형으로 변환?

bestdevel 2020. 11. 28. 10:10
반응형

Convert.ChangeType 및 열거 형으로 변환?


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(.... 당신이 찾고있는 것입니다!

씨 #

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

VB.NET

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

Enum 변환을 많이 수행하면 다음 클래스를 사용하여 많은 코드를 절약 할 수 있습니다.

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);.


@Peter의 답변에 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)은 많은 시나리오에서 유용합니다. 예를 들어 Asp.NET의 WebApi 컨트롤러에는 잘못된 Enum 매개 변수에 대한 기본 보호 기능이 없습니다. 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에 Enum을 저장하고 있지만 어떤 열이 enum이고 어떤 열이 문자열 / int인지 모르는 경우 다음과 같이 값에 액세스 할 수 있습니다.

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));
    }
}

참고 URL : https://stackoverflow.com/questions/507059/convert-changetype-and-converting-to-enums

반응형