5

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?

3
  • What exactly are you trying to achieve? Commented Jun 4, 2010 at 10:11
  • @Robert, lets say I had a typical enum containing values ready,set,go - now when I do a myEnum.ToString() I get the string value ready,set,go printed out (depending on if enum is 1,2,3). What I am trying to do is localize this string value depending on the culture, the Enum.ToString should print the value based on the current culture. Commented Jun 4, 2010 at 10:14
  • @JL added an answer that localizes an enum. Should note that you cannot localize enum strings with Enum.ToString(), but you can achieve localization via a method to convert an enum into a resource string, which you can then retrieve from resources. Commented Jun 7, 2010 at 4:11

5 Answers 5

10

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!

Sign up to request clarification or add additional context in comments.

Comments

1

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.

5 Comments

Enums cannot inherit from anything. They all inherit from System.Enum. In any case, in the above example the OP is basing his enum on the default of int. The problem is that he is trying to dynamically assign the enum's value.
I'll keep the question open for now, I had through of your suggestion, but it could be possible there is a more cleaner solution, thanks Adam.
Sorry, I suppose they cannot inherit. But they can specify a type: public enum MyShorts : short { }
Yes, although it looks a little like inheritance it is actually just changing the underlying representation.
Hi JL. A "cleaner" solution would be to make this utility method an extension method on your enum, I just tried this and it works fine. It would be the same solution, but the utility method would be housed on the type itself. HTH.
1

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.

3 Comments

Anyway to have a static resource?
I think this is the crux of the matter, no dynamic assignment, no matter what (resource or any other dynamic field). So I guess Enum is the wrong tool for the job in this case.
But this would still be runtime behaviour - not compile time for the enum.
1

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.)

1 Comment

your use of generics is perhaps overkill and is unnecessary. All enums are of type Enum. You don't want to call string.Format just to concatenate 2 strings.
1

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); } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.