Enum'da bir dize arayın ve Numarayı döndürün


163

Bir numaralandırma var:

public enum MyColours
{
    Red,
    Green,
    Blue,
    Yellow,
    Fuchsia,
    Aqua,
    Orange
}

ve ben bir dize var:

string colour = "Red";

Geri dönmek istiyorum:

MyColours.Red

dan:

public MyColours GetColour(string colour)

Şimdiye kadar var:

public MyColours GetColours(string colour)
{
    string[] colours = Enum.GetNames(typeof(MyColours));
    int[]    values  = Enum.GetValues(typeof(MyColours));
    int i;
    for(int i = 0; i < colours.Length; i++)
    {
        if(colour.Equals(colours[i], StringComparison.Ordinal)
            break;
    }
    int value = values[i];
    // I know all the information about the matched enumeration
    // but how do i convert this information into returning a
    // MyColour enumeration?
}

Gördüğünüz gibi biraz sıkıştım. Bir numaralandırıcıyı değere göre seçmek için yine de var mı? Gibi bir şey:

MyColour(2) 

sonuç verecek

MyColour.Green


4
@nawfal, bunu yıllar önce sorduğumda bulamadım. Kopyasını kapatmak için oy verdiler.
Matt Clarkson

Yanıtlar:


381

System.Enum.Parse'a göz atın:


enum Colors {Red, Green, Blue}

// your code:
Colors color = (Colors)System.Enum.Parse(typeof(Colors), "Green");


72
Üçüncü bir isteğe bağlı parametreyi "gerçek" olarak geçirerek büyük / küçük harf duyarlılığını yok
sayabileceğini unutmayın

Tam aradığım şey! Şerefe!
Zame

11
@ user1531040 Aslında, bir Enum.TryParse var.
DarLom

Girdi sayısal ise enum ayrıştırma işleminin her zaman 'başarılı' olduğuna dikkat edin; ayrıştırılan sayıyı döndürür ve numaralandırma türüne aktarılır. Bu nedenle, bazı kullanıcı girişlerinin geçerli bir numaralandırma mı yoksa başka bir şey mi olduğunu kontrol etmek istiyorsanız, önce sayısal içeriği kontrol etmelisiniz. Geçerli bir numaralandırma döndürdüğü için, ancak tanımlanmış numaralandırma adlarında hiç bulunmayabilecek bir değere sahip olduğundan, gerçekten garip sorunlar yaşayabilirsiniz.
Nyerguds

19

İnt bir numaraya atabilirsiniz

(MyColour)2

Enum.Parse seçeneği de vardır.

(MyColour)Enum.Parse(typeof(MyColour), "Red")

11

.NET (+ Core) ve C # 7'deki en son ve en büyük değişiklikler göz önüne alındığında, işte en iyi çözüm:

var ignoreCase = true;
Enum.TryParse("red", ignoreCase , out MyColours colour);

renk değişkeni Enum kapsamında kullanılabilir.



2

OregonGhost'un +1 yanıtını işaretledim, sonra yinelemeyi kullanmaya çalıştım ve Enum.GetNames dizeleri döndürdüğünden bunun doğru olmadığını fark ettim. Enum.GetValues ​​değerini istiyorsunuz:

public MyColours GetColours(string colour)
{  
   foreach (MyColours mc in Enum.GetValues(typeof(MyColours))) 
   if (mc.ToString() == surveySystem) 
      return mc;

   return MyColors.Default;
}

1

Enum.ParseAdından bir enum değeri almak için kullanabilirsiniz . Enum.GetNamesİnt ile tüm değerleri yineleyebilir ve int değerinden enum değerini almak için bir int numarasına int atayabilirsiniz.

Bunun gibi, örneğin:

public MyColours GetColours(string colour)
{
    foreach (MyColours mc in Enum.GetNames(typeof(MyColours))) {
        if (mc.ToString().Contains(colour)) {
            return mc;
        }
    }
    return MyColours.Red; // Default value
}

veya:

public MyColours GetColours(string colour)
{
    return (MyColours)Enum.Parse(typeof(MyColours), colour, true); // true = ignoreCase
}

İkincisi, değer bulunmazsa bir ArgumentException kurar, bunu işlevin içinde yakalamak ve varsayılan değeri döndürmek isteyebilirsiniz.


NOT: Tabii, Colin'in cevabında gösterildiği gibi, Enum.GetValues ​​olmalı.
OregonGhost

1
var color =  Enum.Parse<Colors>("Green");

Bu bile derlenmiyor. Genel bir Parseyöntem yoktur .
João Menighin

Benim için derledi ve çalıştı. Belki kullandığınız sürüme bağlıdır? .NET core 3.1
Vinni

0

Önceki yanıtlarda belirtildiği gibi, doğrudan altta yatan veri türüne (int -> enum türü) veya ayrıştırmaya (string -> enum türü) yayınlayabilirsiniz.

ancak dikkat - numaralandırmalar için TryParse yoktur, bu yüzden hataları yakalamak için ayrıştırma etrafında bir try / catch bloğu gerekir.


3
Bu soru sorulmadan önce değildi, ama şimdi .NET 4'ten itibaren var! msdn.microsoft.com/en-us/library/system.enum.tryparse.aspx . O (renk dışarı "Kırmızı",) Enum.TryParse <MyColour> gibi bir şey olurdu
WienerDog

0
class EnumStringToInt // to search for a string in enum
{
    enum Numbers{one,two,hree};
    static void Main()
    {
        Numbers num = Numbers.one; // converting enum to string
        string str = num.ToString();
        //Console.WriteLine(str);
        string str1 = "four";
        string[] getnames = (string[])Enum.GetNames(typeof(Numbers));
        int[] getnum = (int[])Enum.GetValues(typeof(Numbers));
        try
        {
            for (int i = 0; i <= getnum.Length; i++)
            {
                if (str1.Equals(getnames[i]))
                {
                    Numbers num1 = (Numbers)Enum.Parse(typeof(Numbers), str1);
                    Console.WriteLine("string found:{0}", num1);
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("Value not found!", ex);
        }
    }
}

2
C # bunun için yerleşik bir işleve sahiptir.
Artemix

bu sorunun cevabı nasıl? çok daha kolay kod için diğer cevaplara bak
Firo

0

Sizin için yararlı olabilecek bir şey (şu ana kadar sağlanan geçerli / iyi yanıtların yanı sıra) burada sağlanan StringEnum fikri

Bununla numaralandırmalarınızı sınıf olarak tanımlayabilirsiniz (örnekler vb.net'te verilmiştir):

<StringEnumRegisteredOnly (), DebuggerStepThrough (), ImmutableObject (True)> Genel NotInheritable Sınıfı eAuthenticationMethod StringEnumBase (Of eAuthenticationMethod) öğesini devralır

Private Sub New(ByVal StrValue As String)
  MyBase.New(StrValue)   
End Sub

< Description("Use User Password Authentication")> Public Shared ReadOnly UsernamePassword As New eAuthenticationMethod("UP")   

< Description("Use Windows Authentication")> Public Shared ReadOnly WindowsAuthentication As New eAuthenticationMethod("W")   

Bitiş Sınıfı

EAuthenticationMethod.WindowsAuthentication ve bu temelde 'atama gibi olur: Bir enum kullanmak gibi Şimdi bu sınıfını kullanabilir W ' mantıksal değeri windowsAuthentication (enum içinde) ve bir özelliklerinden bu değer görüntülemek için olsaydı penceresi (veya System.ComponentModel.Description özelliğini kullanan başka bir şey) " Windows Kimlik Doğrulaması Kullan " alırsınız .

Bunu uzun zamandır kullanıyorum ve kodun daha net olmasını sağlıyor.


0
(MyColours)Enum.Parse(typeof(MyColours), "red", true); // MyColours.Red
(int)((MyColours)Enum.Parse(typeof(MyColours), "red", true)); // 0

-1

Bu blog yayınındaki önerilerin bazılarına da göz atmak isteyebilirsiniz: Yeni küçük arkadaşım Enum <T>

Gönderi, çirkin döküm sözdiziminden kaçınmanıza izin veren çok basit bir genel yardımcı sınıf yaratmanın bir yolunu açıklıyor Enum.Parse- bunun yerine kodunuza böyle bir şey yazıyorsunuz:

MyColours colour = Enum<MyColours>.Parse(stringValue); 

Ya da aynı gönderiye benzer bir sonuç elde etmek için bir uzantı yöntemi kullanma hakkında konuşan bazı yorumlara göz atın.


Posta bağlantısı bozuk.
Machado
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.