C# DisplayAttribute.GetName 具有特定文化

C# DisplayAttribute.GetName with specific culture

假设我们有一个枚举:

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

作为 Enum 类型的扩展方法很好地提供了一点反射可以达到目的,因为默认情况下每个资源都有一个 public [=13= 的静态实例] class,负责管理资源。

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 上测试