Используя VS2010 и .net V4.0 I хотел бы достигнуть следующего:
У меня уже есть 2 файла ресурсов в моем проекте для 2 языков - английский и чешский язык.
Я должен сказать, что управление ресурсами в .NET превосходно, я удивлен даже получить завершение кода при реализации Строки, например:
string desc = Strings.ResourceManagerDesc
Это связало строку с текущей культурой потока.
Теперь я пытаюсь создать Перечисление, которое может иметь Часть строки Перечисления, интерпретируемого от Строковых ресурсов. Следующим образом (Этот код НЕ РАБОТАЕТ):
public enum DownloadStatus
{
1 = Strings.DownloadState_Complete,
2 = Strings.DownloadState_Failed,
3 = Strings.DownloadState_InProgress
}
Это - составленный пример, но Вы видите точку здесь. Так как вышеупомянутый код не будет работать, там лучшая практика способ достигнуть того, что я хочу?
Перечисления компилируются как часть сборки. По сути, вы присваиваете методу значение перечисления, которое не является константой - CLR недостаточно умна, чтобы вычислить значение во время компиляции, оно должно быть константой.
Я бы предложил создать отдельное перечисление для каждого языка (забудьте о ресурсах) и использовать вспомогательный класс для возврата правильного значения в зависимости от необходимого языкового контекста.
IMO, значение Enum должно быть отражено в домене и не должно быть специфичным для пользовательского интерфейса (языкового контекста).
Вы можете сделать это
public enum DownloadStatus
{
Complete = 1,
Failed = 2,
InProgress = 3
}
и использовать какой-либо метод EnumHelper для получения описания языка и региональных параметров на уровне пользовательского интерфейса
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. )
Перечисления не могут наследовать от строк. В коде вам не нужно беспокоиться о языке кода, поэтому ваше перечисление может просто содержать соответствующие состояния.
Похоже, что вам нужен служебный метод для преобразования значения перечисления в соответствующее строковое представление - просто создайте для этого метод.
РЕДАКТИРОВАТЬ: когда вы используете перечисление для включения кейсов, но вам нужна дополнительная информация для каждого перечисляемого значения, я обычно отбрасываю перечисление и создаю множество статических ссылок и вместо этого использую их в проверке. Эта ссылка может быть классом, содержащим значение перечисления, которое затем может предоставлять полезные заголовки или описания.
Вы можете получить ресурс через строку, а поскольку вы можете преобразовать перечисление в строку, это довольно просто.
enum Whatever { Ready, Set, Go }
public static string GetEnumerationString(Enum enumeration)
{
string resourceName =
string.Concat(enumeration.GetType().Name, "_", enumeration);
return ResourceManager.GetString(resourceName);
}
Теперь в этой реализации мы добавляем ко всем ресурсам перечисления префикс имени перечисления. В нашем проекте это просто предотвращает конфликты с другими ресурсами и упрощает их поиск. Затем вам нужно будет обеспечить добавление ресурсов с именами Whatever_Ready, Whatever_Set и Whatever_Go.
Точно так же, если вы посмотрите на сгенерированный код для статических строк-членов, как вы изначально написали, вы, вероятно, увидите:
public static string DownloadStatus_Complete
{
return ResourceManager.GetString("DownloadStatus_Complete", Resource.Culture);
}