C# String Resource Values as Enum String Part values?
Using VS2010 and .net V4.0 I would like to achieve the following:
I already have 2 resource files in my project for 2 languages - English and Czech.
I must say Resource Management in .net is excellent, I am suprised even to get code completion when implementing a String for example:
string desc = Strings.ResourceManagerDesc
This gets the string associated with the current culture of the thread.
Now I am trying to create an Enum that can have the String portion of the Enum interpreted from the Strings resources. In the following way (This code DOES NOT WORK):
public enum DownloadStatus
{
1 = Strings.DownloadState_Complete,
2 = Strings.DownloadState_Failed,
3 =开发者_开发问答 Strings.DownloadState_InProgress
}
This is a made up example, but you can see the point here. Since the above code won't work, is there a best practice way to achieve what I want?
This question is old but does not have an accepted answer and I was looking for a good way to do this.
Here's what I did, I built an extension to my Enum so that it returns a value from the Resource Manager :
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);
}
}
I hope this can help someone!
Enums cannot inherit from strings. In code you do not need to be concerned with the language of the code, so your enum can simply contain the relevant states.
Looks like what you need is a utility method to convert the enum value to the relevant string representation - simply make a method for this.
EDIT: when you use an enum to switch on cases, but need further information per enumerated value, I tend to drop the enum and create a host of static references and use those in the check instead. This reference can be a class wrapping an enum value, which could then expose helpful titles or descriptions.
Enums are compiled up as part of the assembly. You're essentially assigning a method to the value of the enum isn't of a constant value - the CLR is not smart enough to work out the value at compile time, it needs to be a constant.
I'd suggest that you create a different enum for each language (forget resources) and use a helper class to return the correct one depending on the langauge-context needed.
IMO, the Enum value should be reflected to the domain and should not specific to UI (language-context).
You may want to do like this
public enum DownloadStatus
{
Complete = 1,
Failed = 2,
InProgress = 3
}
and using some EnumHelper method to get culture specific description in the UI layer
var downloadStatusString = EnumHelper.GetDescription<DownloadStatus>(DownloadStatus.Complete);
and EnumHelper class will read the culture specific string from the Resource file
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;
}
}
Note: the resource file name is EnumDescriptions and the key must be this conversion YourNamespace.EnumType_EnumValueInString
. (I'm using HttpContext to get the resource value and you might want to change it if you are not using ASP.Net.)
You can get a resource via a string, and since you can convert an enum to a string, this is quite straightforward.
enum Whatever { Ready, Set, Go }
public static string GetEnumerationString(Enum enumeration)
{
string resourceName =
string.Concat(enumeration.GetType().Name, "_", enumeration);
return ResourceManager.GetString(resourceName);
}
Now in this implementation we prefixing all enum resources with the name of the enum. In a project we did it just prevents collisions with other resources and makes them easy to find. You'd have to then ensure adding resources called Whatever_Ready, Whatever_Set and Whatever_Go.
Similarly, if you were to look at the generated code for the static member Strings as you originally wrote you'd probably see:
public static string DownloadStatus_Complete
{
return ResourceManager.GetString("DownloadStatus_Complete", Resource.Culture);
}
精彩评论