首页 > 解决方案 > 具有特定文化的 C# DisplayAttribute.GetName

问题描述

假设我们有一个枚举:

public enum Foo 
{ 
   [Display(ResourceType = typeof(ModelStrings), Name = "Foo_Bar_Name")]
   Bar,
   [Display(ResourceType = typeof(ModelStrings), Name = "Foo_Far_Name")]
   Far 
}

我们拥有ModelStrings具有多个语言环境的资源。

ModelStrings.en-US.resx, ModelStrings.pt-BR.resx, ModelStrings.fr-FR.resx, etc..

我该如何做这样的事情来检索特定文化的资源价值?

Foo myEnum = Foo.Bar;

var displayName = myEnum.GetDisplayName("pt-BR");

标签: c#localization

解决方案


作为类型的扩展方法提供的一点点反射Enum可以解决问题,因为每个资源,默认情况下,都有一个ResourceManager类的公共静态实例,负责管理资源。

using System;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Reflection;
using System.Resources;
// ...

public static class EnumExtensions
{ 
     public static string GetDisplayName(this Enum enumValue, string cultureName)
     {
         return GetDisplayName(enumValue, CultureInfo.GetCultureInfo(cultureName ?? CultureInfo.CurrentCulture.Name));
     }

     public static string GetDisplayName(this Enum enumValue, CultureInfo cultureInfo)
     {
         var attribute = enumValue.GetType().GetMember(enumValue.ToString())[0].GetCustomAttribute<DisplayAttribute>();

         var resourceType = attribute.ResourceType;
         var resourceKey = attribute.Name;

         var resourceManagerMethodInfo = resourceType.GetProperty(nameof(ResourceManager), BindingFlags.Public | BindingFlags.Static);

         var resourceManager = (ResourceManager)resourceManagerMethodInfo?.GetValue(null);

         return resourceManager?.GetString(resourceKey, cultureInfo);
     }
 }

因此,我们可以像这样简单地使用它:

Foo myEnum = Foo.Bar;

var displayName = myEnum.GetDisplayName("pt-BR"); // The extension method.

在 .NET Core 3.1 上测试


推荐阅读