문제

최선의 방법은 무엇일을 변환할 문자열을 열거 값 C#?

나는 HTML 태그 선택을 포함하는 값의 열거에 있습니다.때 페이지에 게시하고 싶 픽업 가치(는 것입 양식에서의 문자열)및 변환을 열거 값입니다.

이상적인 세계에서 나는 뭔가를 할 수 있습니다:

StatusEnum MyStatus = StatusEnum.Parse("Active");

하지만 그 유효한 코드입니다.

도움이 되었습니까?

해결책

습니다.NET Core.NET>4 이 일반적인 구문 분석하는 방법:

Enum.TryParse("Active", out StatusEnum myStatus);

이것도 포함되어 있 C#7 의 새로운 인라인 out 변수,그래서 이 try-구문 분석,로 변환하여 명시적인 열거 입력하고 처음 상태+을 채웁 myStatus 변수가 있습니다.

액세스 권한이 있는 경우 C#7 습니다.그물이 가장 좋은 방법입니다.

원본 응답

습니다.NET 그것은 오히려 추(까지 4 개 또는 그 이상):

StatusEnum MyStatus = (StatusEnum) Enum.Parse(typeof(StatusEnum), "Active", true);

는 간소화하이:

public static T ParseEnum<T>(string value)
{
    return (T) Enum.Parse(typeof(T), value, true);
}

그때 나는 할 수 있습니다:

StatusEnum MyStatus = EnumUtil.ParseEnum<StatusEnum>("Active");

하나의 옵션에서 제시한 의견에 추가 확장,는 간단하다:

public static T ToEnum<T>(this string value)
{
    return (T) Enum.Parse(typeof(T), value, true);
}

StatusEnum MyStatus = "Active".ToEnum<StatusEnum>();

마지막으로,당신은 당신이 있어야 할 수 있습니다 기본 열거하는 경우 사용할 문자열을 구문 분석할 수 없습니다:

public static T ToEnum<T>(this string value, T defaultValue) 
{
    if (string.IsNullOrEmpty(value))
    {
        return defaultValue;
    }

    T result;
    return Enum.TryParse<T>(value, true, out result) ? result : defaultValue;
}

는 이 전화:

StatusEnum MyStatus = "Active".ToEnum(StatusEnum.None);

그러나,그렇게 될 것이라고 주의를 추가하는 확장과 같은 방법 이해 string 으로(없이는 네임스페이스 제어)에 나타납니다 모든 인스턴스 string 지 여부를 잡는 열거나지 않는다(그래서 1234.ToString().ToEnum(StatusEnum.None) 유효한 것이지만 무의미한).그것은 종종을 피하기 위해 최선을 어지럽히 마이크로 소프트의 핵심 클래스가 추가하는 방법에만 적용에서 아주 특정 상황하지 않는 한 당신의 전체 개발 팀은 매우 좋은 이해의 이러 확장자는 않습니다.

다른 팁

Enum.TryParse<T>(String, T) (≥.NET4.0):

StatusEnum myStatus;
Enum.TryParse("Active", out myStatus);

그것은 간소화할 수 있습니다 더욱 C#7.0 의 인라인 매개변수 유형:

Enum.TryParse("Active", out StatusEnum myStatus);

참고의 성능 Enum.Parse()이기 때문에,그것은 구현을 통해 반영합니다.(같은 사실의 Enum.ToString,는 다른 방법이다.)

변환해야 하는 경우 문자열을 왜냐하면 성능에 민감한 코드,당신의 최선의 방법을 만드는 것입 Dictionary<String,YourEnum> 시작할 때 사용하는 것을 당신의 전환이다.

Enum.구문 분석.

SomeEnum enum = (SomeEnum)Enum.Parse(typeof(SomeEnum), "EnumValue");

당신이 사용할 수 있는 방법 확장 지금:

public static T ToEnum<T>(this string value, bool ignoreCase = true)
{
    return (T) Enum.Parse(typeof (T), value, ignoreCase);
}

당신은 그들에게 전화 할 수 있습니에 의해 아래 코드(여기서, FilterType 은 열거 입력):

FilterType filterType = type.ToEnum<FilterType>();
object Enum.Parse(System.Type enumType, string value, bool ignoreCase);

그래서 만약 당신이 있었는 열거된 분위기 그것은 다음과 같이 보일 것입니다.

   enum Mood
   {
      Angry,
      Happy,
      Sad
   } 

   // ...
   Mood m = (Mood) Enum.Parse(typeof(Mood), "Happy", true);
   Console.WriteLine("My mood is: {0}", m.ToString());

주의:

enum Example
{
    One = 1,
    Two = 2,
    Three = 3
}

Enum.(Try)Parse() 지 여러,쉼표로 구분 인수를,그리고 그들을 결합과 진'또는' |.당신이 사용하지 않도록 설정할 수 없이고 내 생각에 당신은 거의 없고 싶습니다.

var x = Enum.Parse("One,Two"); // x is now Three

는 경우에도 Three 정의되지 않았, x 을 얻을 것이 여전히 int value 3.는 더 악화:Enum.Parse()을 줄 수 있는 가치 있는지에 대해 정의된 열거!

나는 원하지 않을 것이 경험의 결과 사용자,기꺼이나 마지 못해 트리거,이는 동작입니다.

또한,언급했듯이,다른 사람에 의해 성능이 이상적이 큰 열거형,즉,선형에서의 번호를 가능한 값입니다.

나는 다음을 제안합니다:

    public static bool TryParse<T>(string value, out T result)
        where T : struct
    {
        var cacheKey = "Enum_" + typeof(T).FullName;

        // [Use MemoryCache to retrieve or create&store a dictionary for this enum, permanently or temporarily.
        // [Implementation off-topic.]
        var enumDictionary = CacheHelper.GetCacheItem(cacheKey, CreateEnumDictionary<T>, EnumCacheExpiration);

        return enumDictionary.TryGetValue(value.Trim(), out result);
    }

    private static Dictionary<string, T> CreateEnumDictionary<T>()
    {
        return Enum.GetValues(typeof(T))
            .Cast<T>()
            .ToDictionary(value => value.ToString(), value => value, StringComparer.OrdinalIgnoreCase);
    }

Enum.구문 분석 는 당신의 친구:

StatusEnum MyStatus = (StatusEnum)Enum.Parse(typeof(StatusEnum), "Active");

을 확장할 수 있습니다 수락과 함께 답변을 기본값을 피하는 예외:

public static T ParseEnum<T>(string value, T defaultValue) where T : struct
{
    try
    {
        T enumValue;
        if (!Enum.TryParse(value, true, out enumValue))
        {
            return defaultValue;
        }
        return enumValue;
    }
    catch (Exception)
    {
        return defaultValue;
    }
}

당신이 그것을 좋아:

StatusEnum MyStatus = EnumUtil.ParseEnum("Active", StatusEnum.None);

우리는 없다고 가정 완벽하게 유효한 입력,그리고 갔으로의 변화@키스의 대답:

public static TEnum ParseEnum<TEnum>(string value) where TEnum : struct
{
    TEnum tmp; 
    if (!Enum.TryParse<TEnum>(value, true, out tmp))
    {
        tmp = new TEnum();
    }
    return tmp;
}
// str.ToEnum<EnumType>()
T static ToEnum<T>(this string str) 
{ 
    return (T) Enum.Parse(typeof(T), str);
}

구문 분석하는 문자열을 TEnum 지 않고도/잡지 않고 TryParse()메소드에서.NET4.5

/// <summary>
/// Parses string to TEnum without try/catch and .NET 4.5 TryParse()
/// </summary>
public static bool TryParseToEnum<TEnum>(string probablyEnumAsString_, out TEnum enumValue_) where TEnum : struct
{
    enumValue_ = (TEnum)Enum.GetValues(typeof(TEnum)).GetValue(0);
    if(!Enum.IsDefined(typeof(TEnum), probablyEnumAsString_))
        return false;

    enumValue_ = (TEnum) Enum.Parse(typeof(TEnum), probablyEnumAsString_);
    return true;
}

슈퍼 간단한 코드를 사용하여 TryParse:

var value = "Active";

StatusEnum status;
if (!Enum.TryParse<StatusEnum>(value, out status))
    status = StatusEnum.Unknown;

나는 다음과 같은 방법 확장 솔루션입니다..

namespace System
{
    public static class StringExtensions
    {

        public static bool TryParseAsEnum<T>(this string value, out T output) where T : struct
        {
            T result;

            var isEnum = Enum.TryParse(value, out result);

            output = isEnum ? result : default(T);

            return isEnum;
        }
    }
}

여기 아래에 나의 구현을 테스트합니다.

using static Microsoft.VisualStudio.TestTools.UnitTesting.Assert;
using static System.Console;

private enum Countries
    {
        NorthAmerica,
        Europe,
        Rusia,
        Brasil,
        China,
        Asia,
        Australia
    }

   [TestMethod]
        public void StringExtensions_On_TryParseAsEnum()
        {
            var countryName = "Rusia";

            Countries country;
            var isCountry = countryName.TryParseAsEnum(out country);

            WriteLine(country);

            IsTrue(isCountry);
            AreEqual(Countries.Rusia, country);

            countryName = "Don't exist";

            isCountry = countryName.TryParseAsEnum(out country);

            WriteLine(country);

            IsFalse(isCountry);
            AreEqual(Countries.NorthAmerica, country); // the 1rst one in the enumeration
        }
public static T ParseEnum<T>(string value)            //function declaration  
{
    return (T) Enum.Parse(typeof(T), value);
}

Importance imp = EnumUtil.ParseEnum<Importance>("Active");   //function call

====================완벽한 프로그램====================

using System;

class Program
{
    enum PetType
    {
    None,
    Cat = 1,
    Dog = 2
    }

    static void Main()
    {

    // Possible user input:
    string value = "Dog";

    // Try to convert the string to an enum:
    PetType pet = (PetType)Enum.Parse(typeof(PetType), value);

    // See if the conversion succeeded:
    if (pet == PetType.Dog)
    {
        Console.WriteLine("Equals dog.");
    }
    }
}
-------------
Output

Equals dog.

내가 사용하는 클래스(강력한 형식 버전이 열거형으로 구문 분석하고 성능을 개선).나는 그것을 발견 on GitHub,그리고 작업해야 합니다.NET3.5too.그것은 몇 가지 메모리 오버헤드를 발생시킬 때문에 그것이 버퍼는 강력한 소프트웨어입니다.

StatusEnum MyStatus = Enum<StatusEnum>.Parse("Active");

이 블로그 게시물 열거–더 구문,향상된 성능과 TryParse 에 NET3.5.

고 코드:https://github.com/damieng/DamienGKit/blob/master/CSharp/DamienG.Library/System/EnumT.cs

을 위한 성능을 도움이 될 수 있습니다:

    private static Dictionary<Type, Dictionary<string, object>> dicEnum = new Dictionary<Type, Dictionary<string, object>>();
    public static T ToEnum<T>(this string value, T defaultValue)
    {
        var t = typeof(T);
        Dictionary<string, object> dic;
        if (!dicEnum.ContainsKey(t))
        {
            dic = new Dictionary<string, object>();
            dicEnum.Add(t, dic);
            foreach (var en in Enum.GetValues(t))
                dic.Add(en.ToString(), en);
        }
        else
            dic = dicEnum[t];
        if (!dic.ContainsKey(value))
            return defaultValue;
        else
            return (T)dic[value];
    }

내가 찾는 것은 여기의 경우 열거는 값이 EnumMember 값을 고려하지 않습니다.그래서 여기서 우리는 이동:

using System.Runtime.Serialization;

public static TEnum ToEnum<TEnum>(this string value, TEnum defaultValue) where TEnum : struct
{
    if (string.IsNullOrEmpty(value))
    {
        return defaultValue;
    }

    TEnum result;
    var enumType = typeof(TEnum);
    foreach (var enumName in Enum.GetNames(enumType))
    {
        var fieldInfo = enumType.GetField(enumName);
        var enumMemberAttribute = ((EnumMemberAttribute[]) fieldInfo.GetCustomAttributes(typeof(EnumMemberAttribute), true)).FirstOrDefault();
        if (enumMemberAttribute?.Value == value)
        {
            return Enum.TryParse(enumName, true, out result) ? result : defaultValue;
        }
    }

    return Enum.TryParse(value, true, out result) ? result : defaultValue;
}

과 예의는 enum:

public enum OracleInstanceStatus
{
    Unknown = -1,
    Started = 1,
    Mounted = 2,
    Open = 3,
    [EnumMember(Value = "OPEN MIGRATE")]
    OpenMigrate = 4
}

당신이 사용하 Enum.구문 분석하는 객체를 가져옵 값에서 열거한 후에 있는 객체를 변경하는 값에 특정 열거 값입니다.캐스팅을 열거 값을 사용하여 변환합니다.ChangeType.참조하시기 바랍에 다음과 같은 코드 조각

public T ConvertStringValueToEnum<T>(string valueToParse){
    return Convert.ChangeType(Enum.Parse(typeof(T), valueToParse, true), typeof(T));
}

이 예제:

 public static T GetEnum<T>(string model)
    {
        var newModel = GetStringForEnum(model);

        if (!Enum.IsDefined(typeof(T), newModel))
        {
            return (T)Enum.Parse(typeof(T), "None", true);
        }

        return (T)Enum.Parse(typeof(T), newModel.Result, true);
    }

    private static Task<string> GetStringForEnum(string model)
    {
        return Task.Run(() =>
        {
            Regex rgx = new Regex("[^a-zA-Z0-9 -]");
            var nonAlphanumericData = rgx.Matches(model);
            if (nonAlphanumericData.Count < 1)
            {
                return model;
            }
            foreach (var item in nonAlphanumericData)
            {
                model = model.Replace((string)item, "");
            }
            return model;
        });
    }

에서 샘플을 보낼 수 있습니다 각 문자열 설정 Enum.하는 경우 Enum 했는 데이터는 당신이 원하는대로의 Enum 유형입니다.

        <Extension()>
    Public Function ToEnum(Of TEnum)(ByVal value As String, ByVal defaultValue As TEnum) As TEnum
        If String.IsNullOrEmpty(value) Then
            Return defaultValue
        End If

        Return [Enum].Parse(GetType(TEnum), value, True)
    End Function
public TEnum ToEnum<TEnum>(this string value, TEnum defaultValue){
if (string.IsNullOrEmpty(value))
    return defaultValue;

return Enum.Parse(typeof(TEnum), value, true);}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top