8 Soru: Dize olarak C # sayısal enum değeri

tarafından oluşturulan soru Fri, Oct 30, 2015 12:00 AM

Aşağıdaki numaralandırmaya sahibim:

 
public enum Urgency {
    VeryHigh = 1,
    High     = 2,
    Routine  = 4
}

Bunun gibi bir enum "değer" dizesi olarak alabilirim:

 
((int)Urgency.Routine).ToString() // returns "4"  

Not: Bu, şunlardan farklıdır:

 
Urgency.Routine.ToString() // returns "Routine"
(int)Urgency.Routine       // returns 4

Bazı sözdizimsel şeker sağlayacak bir uzantı sınıfı veya statik bir sınıf oluşturabilir miyim? :)

    
52
  1. Aradıklarınız hakkında daha kesin olabilir misiniz?
    2010-08-09 22: 35: 36Z
  2. i.e. enumValue.ToValueString () == int değeri?
    2010-08-09 22: 36: 38Z
  3. Altta yatan int değeri - ancak bir dize olarak (bir dize olarak enum değil) Bir int için sonra da bir dize için atachane sözdizimini hatırlamak yerine, any Enum değerini alan bir yöntemi olan statik sınıf kullanımı kolaylaştırır. Dilin neyin peşinde olduğumu desteklemeyeceğinden şüpheliyim.
    2010-08-09 22: 42: 29Z
  4. .. sanırım istediğini yaptım.
    2010-08-09 23: 07: 03Z
8 Yanıtlar                              8                         

Format dizesini vermek için Enums ToString yönteminin aşırı yüklerini kullanabilmelisiniz, bu enum değerini bir dizge olarak basar.

 
public static class Program
{
    static void Main(string[] args)
    {
        var val = Urgency.High;
        Console.WriteLine(val.ToString("D")); 
    }
}

public enum Urgency 
{ 
    VeryHigh = 1,
    High = 2,
    Low = 4
}
    
99
2010-08-09 23: 23: 26Z
  1. Boş. Güzel basitlik. Cevabımı silmek istememi sağlıyor! 1
    2010-08-09 23: 28: 48Z
  2. Evet, aynı sonucu sorguya farklı bir yaklaşımla sunarken hoş bir yanal düşünce. public static string NumberString(this Enum enVal){return enVal.ToString("D");} kodu fikrinizi alan ve sorulan uzantı yöntemine dönüştüren şey olmalıdır.
    2010-08-09 23: 38: 46Z
  3. Harika şeyler ... Aşağıdaki cevabımı görün
    2010-08-10 01: 44: 06Z
  4. Bunu, uzatma yöntemini kullanan diğerlerinden daha çok seviyorum. Uzantı yöntemi oluşturarak, kodunuza sadece gereksiz bağımlılık ekleyin. Kodunuzda en az bağımlılığa sahip olduğunuzu unutmayın!
    2010-08-10 03: 51: 25Z
  5. Birden çok enum değerine uygulamak için (örnek): new[] { ProductStatus.Open, ProductStatus.Deprecated }.Select(s => s.ToString("D"))
    2016-01-15 09: 12: 38Z

Enums'ler için daha "insan tarafından okunabilir" açıklamalar elde etmek için (örneğin, örneğinizde "Çok Yüksek" yerine "Çok Yüksek") enum değerlerini aşağıdaki gibi özniteliklerle dekore ettim:

 
public enum MeasurementType
{
    Each,

    [DisplayText("Lineal Metres")]
    LinealMetre,

    [DisplayText("Square Metres")]
    SquareMetre,

    [DisplayText("Cubic Metres")]
    CubicMetre,

    [DisplayText("Per 1000")]
    Per1000,

    Other
}


public class DisplayText : Attribute
{

    public DisplayText(string Text)
    {
        this.text = Text;
    }


    private string text;


    public string Text
    {
        get { return text; }
        set { text = value; }
    }
}

Ardından, böyle bir uzantı yöntemi kullandı:

 
    public static string ToDescription(this Enum en)
    {

        Type type = en.GetType();

        MemberInfo[] memInfo = type.GetMember(en.ToString());

        if (memInfo != null && memInfo.Length > 0)
        {

            object[] attrs = memInfo[0].GetCustomAttributes(
                                          typeof(DisplayText),

                                          false);

            if (attrs != null && attrs.Length > 0)

                return ((DisplayText)attrs[0]).Text;

        }

        return en.ToString();

    }

Daha sonra arayabilirsin

 
myEnum.ToDescription()
numaralandırmanızı daha okunabilir bir metin olarak görüntülemek için.     
23
2010-08-10 23: 22: 33Z
  1. vay, bu da bu sorun için oldukça hasta bir çözüm
    2010-08-09 23: 03: 26Z
  2. Benzer yaptım, ancak çoğu zaman yalnızcadeve kasası toplantısı. Sorunun sorduğu şeyi yapmaz.
    2010-08-09 23: 24: 53Z
  3. mükemmel cevap, ancak sorduğu soru için değil.
    2010-08-09 23: 44: 27Z
  4. Teşekkürler - ancak int değerini döndürmez - bir dize olarak :)
    2010-08-10 01: 40: 46Z
  5. DisplayText özelliğinin bildirimini eklemediniz. Muhtemelen ekler misin?
    2010-08-10 11: 51: 59Z

Bu numaralandırmayla sadece ilgilenmek istiyorsanız, Mark Byer'in çözümünü kullanın.

Daha genel bir çözüm için:

 
public static string NumberString(this Enum enVal) 
{
    return Convert.ToDecimal(enVal).ToString("0");
}

Ondalık dönüştürmek, izin verilen 8 farklı temel tür integral türüyle açıkça uğraşmanıza gerek kalmayacağı anlamına gelir; çünkü hepsi kayıpsız bir şekilde ondalık sayıya dönüştürür, ancak birbirleri arasında değil (ulong ve uzun bir süre aralarında kayıpsız bir şekilde dönüştürme yapmazsınız) her ikisi de gerisini halledebilir). Bunu yapmak muhtemelen daha hızlı olacaktır (özellikle, karşılaştırma sıranızda iyi bir seçim yaparsanız), ancak nispeten az kazanç için çok daha ayrıntılı.

Düzenleme:

Yukarıdakiler Frankentosh'unki kadar iyi değil, Frankentosh soruyu asıl sorunla gördü ve çok iyi çözdü.

    
4
2010-08-09 23: 56: 18Z

Küçük bir yansıma nasıl olur? Tüm temel türlerle çalışmalı.

 
public static class EnumTools
{
    public static string ToRawValueString(this Enum e)
    {
        return e
            .GetType()
            .GetFields(BindingFlags.Public | BindingFlags.Static)
            .First(f => f.Name==e.ToString())
            .GetRawConstantValue()
            .ToString();
    }
}

Ardından:

 
Console.WriteLine(Urgency.High.ToRawValueString()); //Writes "2"
    
3
2010-08-09 23: 08: 46Z
  1. gotta luv it ...
    2010-08-09 23: 02: 45Z
  2. First (), numaralandırmada değeriyle eşleşen tanımlanmış bir değer yoksa, özellikle bayrak sayıları ile ortak olan ve diğer durumlarda mümkün olduğunda (), Enum.IsDefined(e.GetType(), e) false döndürür) Bunun böyle bir durum için daha savunmalı olması gerekir ve sonra geçerli (uygunsuzsa) bir değerde başarısız olmamak için geri dönüş, yeniden yapılandığınızda ne zaman olacağınıza yansıma yapmayan yaklaşımı kullanmak olacaktır. daha sonra çok daha hızlı olmadıkça yansıma bitini silin.
    2010-08-09 23: 32: 48Z
  3. @ Jon: Bir Enum türünün bunun için nasıl bir giriş içermediğini anlamıyorum. Neyi kaçırıyorum? EDIT: Gotcha, Enum ORed bayrakları olabilir. Yorumunuzla aynı fikirdeyim.
    2010-08-09 23: 46: 01Z
  4. Bu en yaygın durumdur. Ayrıca, alttaki türün herhangi bir değerini bir enum türüne atmak için de geçerlidir, bu nedenle bir yöntemin geçersiz bir argümanı veya bir özellik için geçersiz bir değer olduğu durumlarda bir tanesini yakalamak için var olan Enum.IsDefined () vardır.
    2010-08-09 23: 53: 06Z

Harika şeyler ... Artık projeme bir uzantı yöntemi ekledim

 
public static class EnumExtensions 
{ 
    public static string NumberString(this Enum enVal) 
    { 
        return enVal.ToString("D"); 
    }
} 

Artık int değerini - bir dize olarak - Urgency.Routine.NumberString();'u arayarak alabilirim. Frankentosh ve Jon'a teşekkürler :)

    
3
2014-12-08 18: 47: 33Z

İsterseniz, uzantı yöntemini tüm numaralar için çalışmasını sağlayabilirsiniz:

 
public static string ToValueString(this Enum enumValue) 
{
    if (enumValue.GetType().GetEnumUnderlyingType() == typeof(int))
        return ((int)(object)enumValue).ToString();
    else if (enumValue.GetType().GetEnumUnderlyingType() == typeof(byte))
        return ((byte)(object)enumValue).ToString();
    ... 
}        
    
2
2010-08-10 01: 10: 30Z
  1. + 1: İlginç ... ama aynı zamanda bu çift oyuncuyu görmek biraz sıra dışı. İyi numara. :) Enum yerine T where T : struct kullanabilir mi?
    2010-08-09 22: 48: 38Z
  2. Haklısın. Bunun neden yardımcı olduğunu düşündüğümden emin değilim. Önerinizi yansıtacak şekilde değiştirildi.
    2010-08-09 23: 01: 00Z

Belirli türünüz için bir uzantı yöntemi yazabilirsiniz:

 
public static class UrgencyExtension
{
    public static string ToIntegerString(this Urgency u)
    {
        return ((int)u).ToString();
    }
}

Aşağıdaki gibi kullanın:

 
Urgency u = Urgency.Routine;
string s = u.ToIntegerString();
    
1
2010-08-09 22: 38: 44Z

basit bir yaklaşım

 
((Urgency)4).ToString() // returns "Routine"
    
1
2019-03-18 09: 30: 35Z
kaynak yerleştirildi İşte
Diğer sorular