我想有一個枚舉,如:可能有用於枚舉的字符串?
enum FilterType
{
Rigid = "Rigid",
SoftGlow = "Soft/Glow",
Ghost = "Ghost",
}
如何實現這一目標?有一個更好的方法嗎?它將用於將要序列化/反序列化的對象實例。它也會填充下拉列表。
我想有一個枚舉,如:可能有用於枚舉的字符串?
enum FilterType
{
Rigid = "Rigid",
SoftGlow = "Soft/Glow",
Ghost = "Ghost",
}
如何實現這一目標?有一個更好的方法嗎?它將用於將要序列化/反序列化的對象實例。它也會填充下拉列表。
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();
}
這是不可能的。 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; }
}
// ...
}
+1用於使類或結構以這種方式運行。 – 2009-10-16 18:45:49
不,這是不可能的。
經批准的類型枚舉是 字節,爲sbyte,短,USHORT,INT,UINT, 長或ulong。
但是,您可以檢索聲明的名稱與枚舉類的枚舉:
string name = Enum.GetName(typeof(FilterType), FilterType.Rigid);
如果這不適合你,一個類可以收集字符串常量的集合。
枚舉總是鏈接到一個整數值。所以不行。 您可以執行FilterType.Rigid.ToString()來獲取字符串值,儘管它不能直接進行本地化。
沒有,但是如果你想的範圍「常量」的字符串,並使用它們像一個枚舉,這裏是我做的:
public static class FilterType
{
public const string Rigid = "Rigid";
public const string SoftGlow = "Soft/Glow";
public const string Ghost ="Ghost";
}
這也是我在過去做過的事情,對於大多數目的都適用。 – Chris 2009-10-16 19:06:45
這種方法的缺點是我看不到如何自動填充下拉菜單。通過一些工作,您至少可以選擇迭代枚舉的值。 – 2009-10-16 19:19:11
@Michael:你可能會迭代一些(雜亂)的反射代碼。 – 2009-10-16 21:41:27
你可以枚舉名作爲這樣
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
如果這還不夠漂亮,你可能想看看自定義屬性,它可以使用反射來檢索...
沒有,但你可以欺騙是這樣的:
public enum FilterType{
Rigid,
SoftGlow,
Ghost
}
然後當你需要他們的〜應變g值你可以做FilterType.Rigid.ToString()
這樣做(我也有罪)顯示用戶文本沒有空格/特殊字符(SoftGlow而不是「Soft/Glow」),我相信他希望能夠做到這一點。 – Pwninstein 2009-10-16 18:09:16
您可以使用屬性在值
[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();
在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());
如果您熟悉擴展方法,你可以很容易做到你以後:
//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());
按照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與屬性的那些字符串。
有趣的方法。只要確保您不要在「高性能」路徑中使用此代碼,因爲執行反射調用的代價相當高昂。 – bobbymcr 2009-10-16 19:03:35
這不是完全可能的。但是,你可以使用數組來僞造它。
首先,創建你枚舉的方式,你會經常一個:
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]);
}
我認爲這個解決方案對於已經(兩年半)接受的答案沒有任何好處,因爲如果您對枚舉進行了任何更改,現在必須保持兩個地方同步。 – Oliver 2012-02-15 14:25:36
好方法。你甚至可以把它作爲所有枚舉的擴展方法。 – 2009-10-16 19:10:48
謝謝..我有很多靜態方法用於處理像這樣的枚舉。但我從來沒有想過使用擴展方法。我不得不試一試 – 2009-10-16 19:25:19
這是一個很好的習慣,通過...在[System.Xml.Serialization.XmlEnum(「Rigid」)]中定義一個更多的屬性.... [Description(「剛性「)]剛性,...等等。 – 2009-10-21 21:48:52