2010-06-04 98 views
5

使用VS2010和.net V4.0我想達到以下目的:C#字符串資源值作爲枚舉字符串部分值?

我已經有2個資源文件在我的項目中用於2種語言 - 英語和捷克語。

我必須說,資源管理.NET是優秀的,我驚訝甚至實現例如字符串時獲得代碼完成:

string desc = Strings.ResourceManagerDesc 

這獲取與線程的當前區域性關聯的字符串。

現在我試圖創建一個Enum,它可以從字符串資源中解釋Enum的字符串部分。以下列方式(這個代碼不工作):

public enum DownloadStatus 
{ 
1 = Strings.DownloadState_Complete, 
2 = Strings.DownloadState_Failed, 
3 = Strings.DownloadState_InProgress 
} 

這是一個由例子,但你可以在這裏看到這一點。由於上述代碼不起作用,是否有最佳實踐方式來實現我想要的?

+0

你究竟想達到什麼目的? – 2010-06-04 10:11:46

+0

@Robert,可以說我有一個典型的枚舉包含值準備,設置,去 - 現在當我做一個myEnum.ToString()我得到字符串值準備好,設置,打印出來(取決於如果枚舉是1,2 ,3)。我想要做的是根據文化本地化這個字符串值,Enum.ToString應該根據當前的文化打印值。 – 2010-06-04 10:14:32

+0

@JL添加了一個本地化枚舉的答案。應該注意的是,你不能使用Enum.ToString()來枚舉枚舉字符串,但是你可以通過一個方法來實現本地化,從而將枚舉轉換成資源字符串,然後你可以從資源中檢索它。 – 2010-06-07 04:11:19

回答

8

這個問題是舊的,但沒有一個公認的答案,我一直在尋找一個很好的方法來做到這一點。

這是我做的,我擴建了我的枚舉,使其從資源管理器返回一個值:

public enum EventType 
    { 
     NewVersion = 1, 
     Accepted = 2, 
     Rejected = 3, 
     BruteForce = 4 
    } 

    public static class EventTypeExtension 
    { 
     public static string Display(this EventType type) 
     { 
      return Strings.ResourceManager.GetString("EventType_" + type); 
     } 
    } 

我希望這可以幫助別人!

1

枚舉被編譯爲程序集的一部分。你基本上將一個方法分配給enum的值不是一個常量值 - CLR在編譯時不夠聰明以便計算出值,它需要是一個常量。

我建議你爲每種語言創建一個不同的枚舉(忘記資源)並根據所需的語言環境使用助手類返回正確的語言。

+0

無論如何有一個靜態資源? – 2010-06-04 10:03:34

+0

我認爲這是問題的關鍵,不要動態分配,不管是什麼(資源或任何其他動態字段)。所以我猜Enum在這種情況下是錯誤的工具。 – 2010-06-04 10:09:23

+0

但是,這仍然是運行時行爲 - 不是枚舉的編譯時間。 – 2010-06-04 10:10:03

1

枚舉不能從字符串繼承。在代碼中,你不需要關心代碼的語言,所以你的枚舉可以簡單地包含相關的狀態。

看起來像你需要的是一種將枚舉值轉換爲相關字符串表示的實用方法 - 只需爲此創建一個方法即可。

編輯:當您使用枚舉打開案例,但每個枚舉值需要更多信息時,我傾向於刪除枚舉並創建一組靜態引用,並在檢查中使用這些引用。這個引用可以是一個包裝枚舉值的類,然後可以公開有用的標題或描述。

+0

枚舉不能從任何東西繼承。它們都從System.Enum繼承。在任何情況下,在上面的例子中,OP都將其enum的默認值設爲int。問題是他試圖動態分配枚舉的值。 – 2010-06-04 10:07:14

+0

現在我會保持這個問題的開放,我已經通過了你的建議,但是可能有更清潔的解決方案,謝謝Adam。 – 2010-06-04 10:07:54

+0

對不起,我想他們不能繼承。但他們可以指定一個類型: public enum MyShorts:short {} – 2010-06-04 10:09:05

1

你可以通過一個字符串獲取資源,既然你可以將一個枚舉轉換爲一個字符串,這很簡單。

enum Whatever { Ready, Set, Go } 

public static string GetEnumerationString(Enum enumeration) 
{ 
    string resourceName = 
     string.Concat(enumeration.GetType().Name, "_", enumeration); 
    return ResourceManager.GetString(resourceName); 
} 

現在在這個實現中,我們爲所有枚舉資源添加了前綴enum的名稱。在我們所做的一個項目中,它只是防止與其他資源發生衝突並使其易於查找。您必須確保添加名爲Whatever_Ready,Whatever_Set和Whatever_Go的資源。

同樣,如果你看的靜態成員字符串生成的代碼,你原來寫你可能會看到:

public static string DownloadStatus_Complete 
{ 
    return ResourceManager.GetString("DownloadStatus_Complete", Resource.Culture); 
} 
0

IMO,枚舉值應該反映到域,並應不特定於UI(語言上下文)。

你可能想要做這樣的

public enum DownloadStatus 
{ 
    Complete = 1, 
    Failed = 2, 
    InProgress = 3 
} 

,並使用一些EnumHelper方法獲取UI層文化的具體描述

var downloadStatusString = EnumHelper.GetDescription<DownloadStatus>(DownloadStatus.Complete); 

和EnumHelper類將讀取的文化特定的字符串資源文件

public static class EnumHelper 
{ 
    public static string GetDescription<T>(T value) 
     where T : struct 
    { 
     if (!typeof(T).IsEnum) 
     { 
      throw new ArgumentException("value must be Enum.", "value"); 
     } 

     var name = value.ToString(); 

     string resourceKey = string.Format(CultureInfo.InvariantCulture, "{0}_{1}", typeof(T).FullName, name); 

     object resource = HttpContext.GetGlobalResourceObject("EnumDescriptions", resourceKey, Thread.CurrentThread.CurrentUICulture); 
     string description = resource as string ?? name; 
     return description; 
    } 
} 

注意:資源文件名是EnumDescriptions和密鑰必須是這個轉換YourNamespace.EnumType_EnumValueInString。 (我使用的HttpContext獲取資源值,如果你不使用ASP.Net你可能想改變它。

+0

您對泛型的使用可能是過度的,也是不必要的。所有的枚舉都是'Enum'類型。你不想調用string.Format來連接2個字符串。 – 2010-06-04 11:16:43