2009-10-16 66 views
7

我想有一個枚舉,如:可能有用於枚舉的字符串?

enum FilterType 
{ 
    Rigid = "Rigid", 
    SoftGlow = "Soft/Glow", 
    Ghost = "Ghost", 
} 

如何實現這一目標?有一個更好的方法嗎?它將用於將要序列化/反序列化的對象實例。它也會填充下拉列表。

回答

11
using System.ComponentModel; 
enum FilterType 
{ 
    [Description("Rigid")] 
    Rigid, 
    [Description("Soft/Glow")] 
    SoftGlow, 
    [Description("Ghost")] 
    Ghost , 
} 

你可以得到價值了這樣

public static String GetEnumerationDescription(Enum e) 
{ 
    Type type = e.GetType(); 
    FieldInfo fieldInfo = type.GetField(e.ToString()); 
    DescriptionAttribute[] da = (DescriptionAttribute[])(fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false)); 
    if (da.Length > 0) 
    { 
    return da[0].Description; 
    } 
    return e.ToString(); 
} 
+4

好方法。你甚至可以把它作爲所有枚舉的擴展方法。 – 2009-10-16 19:10:48

+1

謝謝..我有很多靜態方法用於處理像這樣的枚舉。但我從來沒有想過使用擴展方法。我不得不試一試 – 2009-10-16 19:25:19

+0

這是一個很好的習慣,通過...在[System.Xml.Serialization.XmlEnum(「Rigid」)]中定義一個更多的屬性.... [Description(「剛性「)]剛性,...等等。 – 2009-10-21 21:48:52

1

這是不可能的。 C#只允許整型枚舉類型(int,short,long等)。您可以創建一個輕量級的「類枚舉」類或使用靜態常量。

static class FilterTypes 
{ 
    public const string Rigid = "Rigid"; 
    // ... 
} 

// or ... 

class FilterType 
{ 
    static readonly FilterType RigidFilterType = new FilterType("Rigid"); 

    string name; 

    FilterType(string name) // private constructor 
    { 
     this.name = name; 
    } 

    public static FilterType Rigid 
    { 
     get { return FilterType.RigidFilterType; } 
    } 

    // ... 
} 
+0

+1用於使類或結構以這種方式運行。 – 2009-10-16 18:45:49

0

不,這是不可能的。

經批准的類型枚舉是 字節,爲sbyte,短,USHORT,INT,UINT, 長或ulong。

但是,您可以檢索聲明的名稱與枚舉類的枚舉:

string name = Enum.GetName(typeof(FilterType), FilterType.Rigid); 

如果這不適合你,一個類可以收集字符串常量的集合。

1

枚舉總是鏈接到一個整數值。所以不行。 您可以執行FilterType.Rigid.ToString()來獲取字符串值,儘管它不能直接進行本地化。

9

沒有,但是如果你想的範圍「常量」的字符串,並使用它們像一個枚舉,這裏是我做的:

public static class FilterType 
{ 
    public const string Rigid = "Rigid"; 
    public const string SoftGlow = "Soft/Glow"; 
    public const string Ghost ="Ghost"; 
} 
+0

這也是我在過去做過的事情,對於大多數目的都適用。 – Chris 2009-10-16 19:06:45

+1

這種方法的缺點是我看不到如何自動填充下拉菜單。通過一些工作,您至少可以選擇迭代枚舉的值。 – 2009-10-16 19:19:11

+0

@Michael:你可能會迭代一些(雜亂)的反射代碼。 – 2009-10-16 21:41:27

1

你可以枚舉名作爲這樣

FilterType myType = FilterType.Rigid; 
String strType = myType.ToString(); 
字符串

但是,您可能會遇到Camel Case/Hungarian符號,但您可以使用這樣的方法輕鬆地將其轉換爲更加用戶友好的字符串(不是最漂亮的解決方案,我將非常感激優化此輸入的輸入) :

Public Shared Function NormalizeCamelCase(ByVal str As String) As String 

    If String.IsNullOrEmpty(str) Then 
     Return String.Empty 
    End If 

    Dim i As Integer = 0 
    Dim upperCount As Integer = 0 
    Dim otherCount As Integer = 0 
    Dim normalizedString As String = str 

    While i < normalizedString.Length 

     If Char.IsUpper(normalizedString, i) Then 
      ''Current char is Upper Case 
      upperCount += 1 
      If i > 0 AndAlso Not normalizedString(i - 1).Equals(" "c) Then 
       ''Current char is not first and preceding char is not a space 
       ''...insert a space, move to next char 
       normalizedString = normalizedString.Insert(i, " ") 
       i += 1 
      End If 
     ElseIf Not Char.IsLetter(normalizedString, i) Then 
      otherCount += 1 
     End If 

     ''Move to next char 
     i += 1 

    End While 

    If upperCount + otherCount = str.Length Then 
     ''String is in all caps, return original string 
     Return str 
    Else 
     Return normalizedString 
    End If 

End Function 

如果這還不夠漂亮,你可能想看看自定義屬性,它可以使用反射來檢索...

1

沒有,但你可以欺騙是這樣的:

public enum FilterType{ 
    Rigid, 
    SoftGlow, 
    Ghost 
} 

然後當你需要他們的〜應變g值你可以做FilterType.Rigid.ToString()

+1

這樣做(我也有罪)顯示用戶文本沒有空格/特殊字符(SoftGlow而不是「Soft/Glow」),我相信他希望能夠做到這一點。 – Pwninstein 2009-10-16 18:09:16

0

您可以使用屬性在值

[System.ComponentModel.Description("Rigid")] 

例如:

enum FilterType 
{ 
    [System.ComponentModel.Description("Rigid")] 
    Rigid, 
    [System.ComponentModel.Description("Soft/Glow")] 
    SoftGlow, 
    [System.ComponentModel.Description("Ghost")] 
    Ghost 
} 

和使用反射來獲取的描述。

枚舉擴展方法:

public static string GetDescription(this Enum en) 
    { 
     var type = en.GetType(); 
     var memInfo = type.GetMember(en.ToString()); 

     if (memInfo != null && memInfo.Length > 0) 
     { 
      var attrs = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false); 
      if (attrs != null && attrs.Length > 0) 
       return ((DescriptionAttribute)attrs[0]).Description; 
     } 
     return en.ToString(); 
    } 

使用它:

FilterType = FilterType.Rigid; 
      string description= result.GetDescription(); 
1

在System.ComponentModel命名空間中還有一類DescriptionAttribute那麼好這裏的工作。

enum FilterType 
{ 
    Rigid, 
    [Description("Soft/Glow")] 
    SoftGlow, 
    Ghost, 
} 

然後得到說明和故障轉移到的ToString()

var descriptionAttribute = Value.GetType() 
.GetField(Value.ToString()) 
.GetCustomAttributes(typeof(DescriptionAttribute), false) 
.OfType <DescriptionAttribute>() 
.FirstOrDefault()??new DescriptionAttribute(Value.ToString()); 
2

如果您熟悉擴展方法,你可以很容易做到你以後:

//Can return string constants, the results of a Database call, 
//or anything else you need to do to get the correct value 
//(for localization, for example) 
public static string EnumValue(this MyEnum e) { 
    switch (e) { 
     case MyEnum.First: 
      return "First Friendly Value"; 
     case MyEnum.Second: 
      return "Second Friendly Value"; 
     case MyEnum.Third: 
      return "Third Friendly Value"; 
    } 
    return "Horrible Failure!!"; 
} 

這樣,你可以這樣做:

Private MyEnum value = MyEnum.First; 
Console.WriteLine(value.EnumValue()); 
0

按照Shaun Bowe的例子,你也可以在C#3中用enum的擴展方法來做到這一點(在我的生活中,我沒有想出和不能,記住我在哪裏做過)。

創建一個屬性:

public class DisplayTextAttribute : Attribute { 
    public DisplayTextAttribute(String text) { 
    Text = text; 
    } 
    public string Text { get; set; } 
} 

創建擴展:

public static class EnumHelpers { 
    public static string GetDisplayText(this Enum enumValue) { 
    var type = enumValue.GetType(); 
    MemberInfo[] memberInfo = type.GetMember(enumValue.ToString()); 

    if (memberInfo == null || memberInfo.Length == 0) 
     return enumValue.ToString(); 

    object[] attributes = memberInfo[0].GetCustomAttributes(typeof(DisplayTextAttribute), false); 
    if (attributes == null || attributes.Length == 0) 
     return enumValue.ToString(); 

    return ((DisplayTextAttribute)attributes[0]).Text; 
    } 
} 

我發現這是真的漂亮的解決方案。 在你的枚舉添加以下內容:

enum FilterType{ 
    Rigid, 
    [DisplayText("Soft/Glow")] 
    SoftGlow, 
    Ghost 
} 

然後,您可以訪問FilterType.GetDisplayText()將拉回了未歸因枚舉和displayText與屬性的那些字符串。

+0

有趣的方法。只要確保您不要在「高性能」路徑中使用此代碼,因爲執行反射調用的代價相當高昂。 – bobbymcr 2009-10-16 19:03:35

1

這不是完全可能的。但是,你可以使用數組來僞造它。

首先,創建你枚舉的方式,你會經常一個:

public enum Regexs 
{ 
    ALPHA = 0, 
    NUMERIC = 1, 
    etc.. 
} 

然後創建持有與枚舉值數組中的值:

private static string[] regexs = new string[] 
{ 
    "[A-Za-z]", 
    "[0-9]", 
    "etc"... 
} 

然後你就可以訪問您的字符串通過枚舉值:

public void runit(Regexs myregexEnum) 
{ 
    Regex regex = new Regex(regexs [(int)myregexEnum]); 
} 
+0

我認爲這個解決方案對於已經(兩年半)接受的答案沒有任何好處,因爲如果您對枚舉進行了任何更改,現在必須保持兩個地方同步。 – Oliver 2012-02-15 14:25:36