แปลงสตริงเป็น enum ใน C #


894

วิธีที่ดีที่สุดในการแปลงสตริงเป็นค่าการแจงนับใน C # คืออะไร

ฉันมีแท็กเลือก HTML ที่มีค่าการแจงนับ เมื่อหน้าถูกโพสต์ฉันต้องการรับค่า (ซึ่งจะอยู่ในรูปแบบของสตริง) และแปลงเป็นค่าการแจงนับ

ในโลกอุดมคติฉันสามารถทำสิ่งนี้:

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

แต่นั่นไม่ใช่รหัสที่ถูกต้อง

คำตอบ:


1508

ใน. NET Core และ. NET> 4 มีวิธีการแยกวิเคราะห์ทั่วไป :

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

นอกจากนี้ยังรวมถึงoutตัวแปรอินไลน์ใหม่ของ C # 7 ด้วยเหตุนี้จึงลองแยกวิเคราะห์การแปลงเป็นประเภท enum อย่างชัดเจนและกำหนดค่าเริ่มต้น + เติมmyStatusตัวแปร

หากคุณสามารถเข้าถึง C # 7 และ. NET ล่าสุดนี่เป็นวิธีที่ดีที่สุด

คำตอบเดิม

ใน. 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>();

ในที่สุดคุณอาจต้องการให้ enum เริ่มต้นใช้หากสตริงไม่สามารถแยกวิเคราะห์:

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ไม่ว่าพวกเขาจะถือ enum หรือไม่ (ดังนั้น1234.ToString().ToEnum(StatusEnum.None)จะถูกต้อง แต่ไร้สาระ) มักจะเป็นการดีที่สุดที่จะหลีกเลี่ยงความยุ่งเหยิงในชั้นเรียนหลักของ Microsoft ด้วยวิธีการพิเศษที่ใช้เฉพาะในบริบทที่เฉพาะเจาะจงเท่านั้นเว้นแต่ทีมพัฒนาทั้งหมดของคุณจะมีความเข้าใจที่ดีเกี่ยวกับส่วนขยายเหล่านั้น


17
หาก performace เป็นสิ่งสำคัญ (ซึ่งมักจะเป็น) คำตอบที่ chk ให้ไว้โดย Mckenzieg1 ด้านล่าง: stackoverflow.com/questions/16100/…
Nash

28
@avinashr ถูกต้องเกี่ยวกับคำตอบของ @ McKenzieG1 แต่มันไม่สำคัญเสมอไป ตัวอย่างเช่นมันจะเป็นการเพิ่มประสิทธิภาพแบบไม่มีจุดหมายขนาดเล็กเพื่อกังวลเกี่ยวกับการแจงนับ enum หากคุณทำการเรียก DB สำหรับการแยกวิเคราะห์แต่ละครั้ง
Keith

4
@HM ฉันไม่คิดว่าส่วนขยายเหมาะสมที่นี่ - เป็นกรณีพิเศษเล็กน้อยและส่วนขยายจะใช้กับทุกสตริง ถ้าคุณอยากจะทำมันแม้ว่ามันจะเป็นการเปลี่ยนแปลงเล็กน้อย
Keith

7
วิธีการเกี่ยวกับ Enum.TryParse?
Elaine

15
ดีมาก. คุณต้องการที่ T: struct ในตัวอย่างสุดท้ายของคุณ
bbrik

330

ใช้Enum.TryParse<T>(String, T)(≥ .NET 4.0):

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

สามารถทำให้ง่ายขึ้นยิ่งขึ้นด้วยการเรียงพารามิเตอร์ชนิด C # 7.0 :

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

45
เพิ่มพารามิเตอร์กลางบูลีนเพื่อให้ตรงตามตัวพิมพ์ใหญ่ - เล็กและนี่คือทางออกที่ปลอดภัยและสง่างามที่สุด
DanM7

18
มาเลยมีกี่คนที่คุณตอบว่าเลือกคำตอบจากปี 2008 เพื่อเลื่อนลงเท่านั้นและพบว่านี่เป็นคำตอบที่ดีกว่า (ทันสมัย)
TEK

@TEK ฉันชอบคำตอบของปี 2008
Zero3

ฉันไม่เข้าใจ Parseพ่นข้อยกเว้นอธิบายสำหรับสิ่งที่ผิดพลาดกับการแปลง (ค่าnullว่างเปล่าหรือไม่มีค่าคงที่ enum ที่สอดคล้องกัน) ซึ่งเป็นวิธีที่ดีกว่าTryParseค่าส่งคืนแบบบูลีน (ซึ่งระงับข้อผิดพลาดที่เป็นรูปธรรม)
yair

2
Enum.TryParse <T> (String, T) มีข้อบกพร่องเมื่อแยกวิเคราะห์สตริงจำนวนเต็ม ตัวอย่างเช่นรหัสนี้จะประสบความสำเร็จในการแยกสตริงที่ไร้สาระเป็น enum ไร้สาระ: var result = Enum.TryParse<System.DayOfWeek>("55", out var parsedEnum);
มวล Dot Net

196

โปรดทราบว่าประสิทธิภาพของEnum.Parse()มันแย่มากเพราะถูกนำมาใช้ผ่านการสะท้อนกลับ (เช่นเดียวกับของจริงEnum.ToStringซึ่งไปในทางอื่น)

หากคุณต้องการแปลงสตริงเป็น Enums ในรหัสที่ไวต่อประสิทธิภาพการดำเนินงานที่ดีที่สุดของคุณคือการสร้างDictionary<String,YourEnum>ตอนเริ่มต้นและใช้เพื่อทำการแปลง


10
ฉันวัด 3ms เพื่อแปลงสตริงเป็น Enum ในการรันครั้งแรกบนคอมพิวเตอร์เดสก์ท็อป (เพียงเพื่อแสดงให้เห็นถึงระดับของความน่าสะพรึงกลัว)
Matthieu Charbonnier

12
ว้าว 3 มิลลิวินาทีเป็นคำสั่งที่แย่มาก
จอห์นสต็อก

1
คุณสามารถเพิ่มโค้ดตัวอย่างได้เราจึงได้แนวคิดในการเปลี่ยนและใช้งาน
transformer

หากแอปของคุณมีผู้ใช้งาน 1 ล้านคน => แอปจะเพิ่มชีวิตมนุษย์มากถึง 50 ชั่วโมงที่คุณกำลังใช้ :) ในการใช้หน้าเว็บครั้งเดียว : P
CătălinRădoi


31

คุณสามารถใช้วิธีการขยายได้ทันที :

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

และคุณสามารถเรียกพวกเขาด้วยรหัสด้านล่าง (ที่นี่FilterTypeเป็นประเภท enum):

FilterType filterType = type.ToEnum<FilterType>();

1
ฉันได้อัปเดตสิ่งนี้เพื่อรับค่าเป็นวัตถุและส่งไปยังสตริงภายในวิธีนี้ วิธีนี้ฉันสามารถใช้ค่า int ไปยัง Toum แทนที่จะเป็นสตริงเท่านั้น
RealSollyM

2
@SollyM ฉันบอกว่าเป็นสาเหตุที่น่ากลัวแล้ววิธีการขยายนี้จะใช้กับทุกประเภทวัตถุ วิธีการขยายสองวิธีสำหรับสตริงและอีกวิธีสำหรับ int จะสะอาดและปลอดภัยกว่าในความคิดของฉัน
Svish

@ เห็นว่าเป็นเรื่องจริง เหตุผลเดียวที่ฉันทำเช่นนี้ก็เพราะรหัสของเราใช้ภายในเท่านั้นและฉันต้องการหลีกเลี่ยงการเขียน 2 ส่วนขยาย และตั้งแต่ครั้งเดียวที่เราแปลงเป็น Enum ด้วยสตริงหรือ int ฉันไม่เห็นว่ามันเป็นปัญหาอย่างอื่น
RealSollyM

3
@SollyM ภายในหรือไม่ฉันยังคงรักษาและใช้รหัสของฉัน: PI จะรำคาญถ้าฉันได้รับ ToEnum ในทุกเมนู Intellisense และเหมือนที่คุณพูดตั้งแต่ครั้งเดียวที่คุณแปลงเป็น Enum จากสตริง หรือ int คุณสามารถมั่นใจได้ว่าคุณจะต้องใช้ทั้งสองวิธีเท่านั้น และวิธีการสองวิธีนั้นไม่ได้มีมากกว่าหนึ่งวิธีโดยเฉพาะอย่างยิ่งเมื่อมีขนาดเล็กและมีประเภทของโปรแกรมอรรถประโยชน์: P
Svish

20
object Enum.Parse(System.Type enumType, string value, bool ignoreCase);

ดังนั้นหากคุณมีอารมณ์ชื่อ enum มันจะมีลักษณะเช่นนี้:

   enum Mood
   {
      Angry,
      Happy,
      Sad
   } 

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

18

ระวัง:

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

Enum.(Try)Parse() ยอมรับหลายคั่นด้วยเครื่องหมายจุลภาคข้อโต้แย้งและรวมพวกเขาด้วยไบนารี |'หรือ' คุณไม่สามารถปิดการใช้งานนี้และในความคิดของฉันคุณเกือบจะไม่ต้องการมัน

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

แม้ว่าThreeไม่ได้กำหนดไว้จะยังคงได้รับค่าx int 3นั่นยิ่งเลวร้ายกว่า: Enum.Parse () สามารถให้คุณค่าที่ไม่ได้กำหนดไว้สำหรับ Enum!

ฉันจะไม่ต้องการประสบกับผลที่ตามมาของผู้ใช้ด้วยความเต็มใจหรือไม่เต็มใจทำให้เกิดพฤติกรรมนี้

นอกจากนี้ตามที่กล่าวไว้โดยผู้อื่นประสิทธิภาพจะน้อยกว่าอุดมคติสำหรับ enums ขนาดใหญ่กล่าวคือเป็นเส้นตรงในจำนวนค่าที่เป็นไปได้

ฉันขอแนะนำดังต่อไปนี้:

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

4
Enum.(Try)Parse accepts multiple, comma-separated arguments, and combines them with binary 'or'ในความเป็นจริงนี้เป็นประโยชน์อย่างมากที่จะรู้ว่า หมายความว่าคุณสามารถตั้งค่า enum เป็นพลังของ 2 และคุณมีวิธีที่ง่ายมากในการแยกวิเคราะห์ธงบูลีนหลายรายการเช่น "UseSSL, NoRetries, ซิงค์" ในความเป็นจริงมันอาจเป็นสิ่งที่มันถูกออกแบบมาสำหรับ
pcdev


13

คุณสามารถขยายคำตอบที่ยอมรับได้ด้วยค่าเริ่มต้นเพื่อหลีกเลี่ยงข้อยกเว้น:

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

ถ้าค่าเริ่มต้นไม่ใช่ enum Enum.TryParse จะล้มเหลวและส่งข้อยกเว้นที่จับได้

หลังจากใช้งานฟังก์ชั่นนี้ในรหัสของเรามาหลายปีอาจจะเป็นการดีที่จะเพิ่มข้อมูลที่การดำเนินการนี้เสียค่าใช้จ่าย!


ฉันไม่ชอบค่าเริ่มต้น มันสามารถนำไปสู่ผลลัพธ์ที่คาดเดาไม่ได้
Daniël Tulp

5
สิ่งนี้จะเกิดข้อยกเว้นเมื่อใด
andleer

@andleer ถ้าค่า enum ไม่พอดีกับชนิด enum เดียวกันกับค่าเริ่มต้น
Nelly

@Nelly รหัสเก่าที่นี่ แต่ชนิดและวิธีการกลับมามีทั้งประเภทdefaultValue Tหากประเภทแตกต่างกันคุณจะได้รับข้อผิดพลาดเกี่ยวกับเวลารวบรวม: "ไม่สามารถแปลงจาก 'ConsoleApp1.Size' เป็น 'ConsoleApp1.Color'" หรือประเภทของคุณคืออะไร
andleer

@andleer ฉันขอโทษคำตอบสุดท้ายของคุณไม่ถูกต้อง เป็นไปได้ว่าวิธีการนี้จะโยน Syste.ArgumentException ในกรณีที่มีคนเรียกใช้ฟังก์ชันนี้ด้วยค่าเริ่มต้นที่ไม่ใช่ประเภท enum ด้วย c # 7.0 ฉันไม่สามารถสร้างส่วนคำสั่ง T: Enum ได้ นั่นเป็นเหตุผลที่ฉันจับความเป็นไปได้นี้ด้วยการลองจับ
Nelly

8

เราไม่สามารถสมมติว่าอินพุตที่ถูกต้องสมบูรณ์และไปพร้อมกับคำตอบของ @ Keith รูปแบบนี้:

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


5

แยกสตริงเป็น TEnum โดยไม่ต้องลอง / จับและไม่มีเมธอด TryParse () จาก. NET 4.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;
}

1
จำเป็นต้องสร้างคำอธิบายหรือไม่หากรหัสมีคำอธิบายอยู่แล้ว? ตกลงฉันทำสิ่งนี้ :)
jite.gs


2

ฉันชอบวิธีแก้ปัญหาส่วนขยาย ..

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
        }

1
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.

1

ฉันใช้คลาส (Enum เวอร์ชันที่พิมพ์อย่างยิ่งพร้อมการแยกวิเคราะห์และปรับปรุงประสิทธิภาพ) ฉันพบมันบน GitHub และควรใช้กับ NET 3.5 ได้เช่นกัน มีหน่วยความจำเหนือหัวเนื่องจากบัฟเฟอร์พจนานุกรม

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

blogpost เป็นEnums - ไวยากรณ์ที่ดีขึ้น, ปรับปรุงประสิทธิภาพและ TryParse ใน NET 3.5

และรหัส: https://github.com/damieng/DamienGKit/blob/master/CSharp/DamienG.Library/System/EnumT.cs


1

เพื่อประสิทธิภาพการทำงานสิ่งนี้อาจช่วย:

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

1

ฉันพบว่าที่นี่กรณีที่มีค่า Enum ที่มีค่า 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
}

1

คุณต้องใช้ Enum.Parse เพื่อรับค่าวัตถุจาก Enum หลังจากนั้นคุณต้องเปลี่ยนค่าวัตถุเป็นค่า enum เฉพาะ การแปลงเป็นค่า enum สามารถทำได้โดยใช้ Convert.ChangeType โปรดดูข้อมูลโค้ดต่อไปนี้

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

1

ลองตัวอย่างนี้:

 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ประเภทของคุณ


1
คุณกำลังเขียนทับnewModelในแต่ละบรรทัดดังนั้นหากมีขีดกลางจะไม่ถูกแทนที่ นอกจากนี้คุณไม่ต้องตรวจสอบว่าสตริงมีอะไรคุณสามารถโทรReplaceต่อไปได้:var newModel = model.Replace("-", "").Replace(" ", "");
Lars Kristensen

@ LarsKristensen ใช่เราสามารถสร้างวิธีการที่ลบอักขระที่ไม่ใช่ตัวเลขและตัวอักษร
AmirReza-Farahlagha

1

ไม่แน่ใจว่าเมื่อมีการเพิ่ม แต่ในคลาส Enum ตอนนี้มี

Parse<TEnum>(stringValue)

ใช้อย่างนั้นด้วยตัวอย่างในคำถาม:

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

หรือไม่สนใจกล่องโดย:

var MyStatus = Enum.Parse<StatusEnum >("active", true)

นี่คือวิธีการถอดรหัสที่ใช้:

    [NullableContext(0)]
    public static TEnum Parse<TEnum>([Nullable(1)] string value) where TEnum : struct
    {
      return Enum.Parse<TEnum>(value, false);
    }

    [NullableContext(0)]
    public static TEnum Parse<TEnum>([Nullable(1)] string value, bool ignoreCase) where TEnum : struct
    {
      TEnum result;
      Enum.TryParse<TEnum>(value, ignoreCase, true, out result);
      return result;
    }

0
        <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

0
public TEnum ToEnum<TEnum>(this string value, TEnum defaultValue){
if (string.IsNullOrEmpty(value))
    return defaultValue;

return Enum.Parse(typeof(TEnum), value, true);}

0

หากชื่อคุณสมบัติแตกต่างจากสิ่งที่คุณต้องการเรียก (เช่นความแตกต่างของภาษา) คุณสามารถทำสิ่งนี้ได้:

MyType.cs

using System;
using System.Runtime.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

[JsonConverter(typeof(StringEnumConverter))]
public enum MyType
{
    [EnumMember(Value = "person")]
    Person,
    [EnumMember(Value = "annan_deltagare")]
    OtherPerson,
    [EnumMember(Value = "regel")]
    Rule,
}

EnumExtensions.cs

using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

public static class EnumExtensions
{
    public static TEnum ToEnum<TEnum>(this string value) where TEnum : Enum
    {
        var jsonString = $"'{value.ToLower()}'";
        return JsonConvert.DeserializeObject<TEnum>(jsonString, new StringEnumConverter());
    }

    public static bool EqualsTo<TEnum>(this string strA, TEnum enumB) where TEnum : Enum
    {
        TEnum enumA;
        try
        {
            enumA = strA.ToEnum<TEnum>();
        }
        catch
        {
            return false;
        }
        return enumA.Equals(enumB);
    }
}

Program.cs

public class Program
{
    static public void Main(String[] args) 
    { 
        var myString = "annan_deltagare";
        var myType = myString.ToEnum<MyType>();
        var isEqual = myString.EqualsTo(MyType.OtherPerson);
        //Output: true
    }     
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.