System.Resources.ResourceManager 构造函数

本文提供了此 API 参考文档的补充说明。

ResourceManager(Type) 构造函数

本部分与 ResourceManager(Type) 构造函数重载有关。

桌面应用

在桌面应用中,资源管理器使用 resourceSource 参数加载特定资源文件,如下所示:

  • 如果NeutralResourcesLanguageAttribute属性未被用来指示默认文化信息的资源驻留在附属程序集中,资源管理器会假定默认文化信息的资源文件与resourceSource参数指定的类型位于同一程序集中。
  • 资源管理器假定默认资源文件具有与参数指定的 resourceSource 类型相同的基名称。
  • 资源管理器使用默认 ResourceSet 类来操作资源文件。

例如,对于名为 MyCompany.MyProduct.MyType 的类型,资源管理器在定义 的程序集中查找名为 MyCompany.MyProduct.MyType.resourcesMyType 文件。

在 Visual Studio 中,资源设计器会自动生成代码,这些代码用于定义一个类(用 C# 是 internal,用 Visual Basic 是 Friend),其名称与默认区域性的 .resources 文件的基名称相同。 这样就可以实例化一个 ResourceManager 对象,并通过获取一个名称对应于资源名称的类型对象,将它与一组特定的资源耦合在一起,因为只要类对编译器可见,资源也必须如此。 例如,如果 .resources 文件名为 Resource1,则以下语句实例化一个 ResourceManager 对象来管理名为 Resource1 的 .resources 文件:

ResourceManager rm = new ResourceManager(typeof(Resource1));

如果不使用 Visual Studio,则可以创建一个没有成员的类,其命名空间和名称与默认 .resources 文件的命名空间和名称相同。 该示例提供了一个插图。

Windows 8.x 应用

重要

尽管 Windows 8.x 应用中支持 ResourceManager 类,但我们不建议使用它。 仅在开发可用于 Windows 8.x 应用的可移植类库项目时才使用该类。 若要从 Windows 8.x 应用检索资源,请改用 Windows.ApplicationModel.Resources.ResourceLoader 类。

在 Windows 8.x 应用中, ResourceManager 使用 resourceSource 参数推断程序集、基名称和命名空间,其中资源项可以位于应用的包资源索引 (PRI) 文件中。 例如,给定一个名为MyCompany.MyProduct.MyType的类型,该类型定义在MyAssembly中,资源管理器将查找名为MyAssembly的资源集标识符,并查找该资源集中的作用域MyCompany.MyProduct.MyType。 资源管理器在默认上下文(当前区域性、当前高对比度设置等)下搜索该范围内的资源项。

示例:

以下示例使用 ResourceManager(Type) 构造函数实例化 ResourceManager 对象。 它包括从英语(en)、法语(法国)(fr-FR)和俄罗斯(俄罗斯)(ru-RU)文化的 .txt 文件中编译的资源。 本示例将当前文化和当前 UI 文化更改为英语(美国)、法语(法国)、俄语(俄罗斯)和瑞典语(瑞典)。 然后,它会调用 GetString(String) 该方法来检索本地化字符串,该字符串显示一个问候语,具体取决于一天的时间。

该示例需要三个基于文本的资源文件,如下表所示。 每个文件都包含命名MorningAfternoon的字符串资源,以及 Evening

文化 文件名 资源名称 资源值
zh-CN GreetingResources.txt Morning 早上好
zh-CN GreetingResources.txt Afternoon 下午好
zh-CN GreetingResources.txt Evening 晚上好
fr-FR GreetingResources.fr-FR.txt Morning 你好
fr-FR GreetingResources.fr-FR.txt Afternoon 你好
fr-FR GreetingResources.fr-FR.txt Evening Bonsoir
ru-RU GreetingResources.ru-RU.txt Morning Доброе утро
ru-RU GreetingResources.ru-RU.txt Afternoon Добрый день
ru-RU GreetingResources.ru-RU.txt Evening Добрый вечер

可以使用以下批处理文件编译 Visual Basic 示例并创建名为 Greet.exe的可执行文件。 若要使用 C# 进行编译,请将编译器名称从 vbc 更改为 csc,并将文件扩展名从 .vb 更改为 .cs

resgen GreetingResources.txt
vbc Greet.vb /resource: GreetingResources.resources

md fr-FR
resgen GreetingResources.fr-FR.txt
al /out:fr-FR\Greet.resources.dll /culture:fr-FR /embed: GreetingResources.fr-FR.resources

md ru-RU
resgen GreetingResources.ru-RU.txt
al /out:ru-RU\Greet.resources.dll /culture:ru-RU /embed: GreetingResources.ru-RU.resources

下面是示例的源代码(visual Basic 版本ShowDate.vb或 C# 版本的代码ShowDate.cs)。

using System;
using System.Resources;
using System.Globalization;
using System.Threading;

[assembly: NeutralResourcesLanguage("en")]

public class Example2
{
    public static void Main()
    {
        string[] cultureNames = [ "en-US", "fr-FR", "ru-RU", "sv-SE" ];
        DateTime noon = new DateTime(DateTime.Now.Year, DateTime.Now.Month,
                                     DateTime.Now.Day, 12, 0, 0);
        DateTime evening = new DateTime(DateTime.Now.Year, DateTime.Now.Month,
                                        DateTime.Now.Day, 18, 0, 0);

        ResourceManager rm = new ResourceManager(typeof(GreetingResources));

        foreach (var cultureName in cultureNames)
        {
            Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(cultureName);
            Console.WriteLine($"The current UI culture is {CultureInfo.CurrentUICulture.Name}");
            if (DateTime.Now < noon)
                Console.WriteLine($"{rm.GetString("Morning")}!");
            else if (DateTime.Now < evening)
                Console.WriteLine($"{rm.GetString("Afternoon")}!");
            else
                Console.WriteLine($"{rm.GetString("Evening")}!");
            Console.WriteLine();
        }
    }

    internal class GreetingResources
    {
    }
}
// The example displays output like the following:
//       The current UI culture is en-US
//       Good afternoon!
//
//       The current UI culture is fr-FR
//       Bonjour!
//
//       The current UI culture is ru-RU
//       Добрый день!
//
//       The current UI culture is sv-SE
//       Good afternoon!
Imports System.Resources
Imports System.Globalization
Imports System.Threading

<Assembly:NeutralResourcesLanguage("en")>

Module Example
   Public Sub Main()
      Dim cultureNames() As String = {"en-US", "fr-FR", "ru-RU", "sv-SE" }
      Dim noon As New Date(Date.Now.Year, Date.Now.Month, 
                           Date.Now.Day, 12,0,0)
      Dim evening As New Date(Date.Now.Year, Date.Now.Month,
                              Date.Now.Day, 18, 0, 0)                          
      
      Dim rm As New ResourceManager(GetType(GreetingResources))
      
      For Each cultureName In cultureNames
         Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(cultureName)
         Console.WriteLine("The current UI culture is {0}", 
                           CultureInfo.CurrentUICulture.Name)
         If Date.Now < noon Then
            Console.WriteLine("{0}!", rm.GetString("Morning"))
         ElseIf Date.Now < evening Then
            Console.WriteLine("{0}!", rm.GetString("Afternoon"))
         Else
            Console.WriteLine("{0}!", rm.GetString("Evening"))
         End If 
         Console.WriteLine()
      Next
   End Sub
End Module

Friend Class GreetingResources
End Class
' The example displays output like the following:
'       The current UI culture is en-US
'       Good afternoon!
'       
'       The current UI culture is fr-FR
'       Bonjour!
'       
'       The current UI culture is ru-RU
'       Добрый день!
'       
'       The current UI culture is sv-SE
'       Good afternoon!

除了定义名为 Example的应用类之外,源代码还定义了一个内部类, GreetingResources其名称与资源文件的基名称相同。 这样就可以通过调用ResourceManager构造函数成功实例化ResourceManager(Type)对象。

请注意,输出会显示适当的本地化字符串,除非当前的 UI 文化是瑞典语(瑞典),在这种情况下,会改为使用英语语言资源。 由于瑞典语言资源不可用,因此应用会改用默认文化的资源,该文化由属性 NeutralResourcesLanguageAttribute 定义。

ResourceManager(String, Assembly) 构造函数

本部分与 ResourceManager(String, Assembly) 构造函数重载有关。

桌面应用

在桌面应用程序中,各个文化特定的资源文件应包含在卫星程序集里,默认文化的资源文件应包含在主程序集里。 假定附属程序集包含该程序集清单中指定的单一区域性的资源,并根据需要进行了加载。

注释

若要直接从 .resources 文件中检索资源,而不是从程序集检索资源,必须改为调用 CreateFileBasedResourceManager 该方法来实例化 ResourceManager 对象。

如果在baseName找不到由assembly标识的资源文件,则该方法将实例化一个ResourceManager对象,但是在尝试检索特定资源时通常会引发MissingManifestResourceException异常。 有关诊断异常原因的信息,请参阅 ResourceManager 类主题的“处理 MissingManifestResourceException 异常”部分。

Windows 8.x 应用

重要

尽管 Windows 8.x 应用中支持 ResourceManager 类,但我们不建议使用它。 仅在开发可用于 Windows 8.x 应用的可移植类库项目时才使用该类。 若要从 Windows 8.x 应用检索资源,请改用 Windows.ApplicationModel.Resources.ResourceLoader 类。

在 Windows 8.x 应用中,资源管理器使用参数的 assembly 简单名称在应用的包资源索引 (PRI) 文件中查找匹配的资源集。 该baseName 参数用于查找资源集合中的资源项。 例如,PortableLibrary1.Resource1 的根名称。de-DE.resources 为 PortableLibrary1.Resource1。

示例:

以下示例使用简单的非本地化“Hello World”应用来演示 ResourceManager(String, Assembly) 构造函数。 名为 ExampleResources.txt 的文本文件的内容为 Greeting=Hello. 编译应用后,资源将嵌入主应用程序集中。

可以在命令提示符下使用 资源文件生成器(ResGen.exe) 将文本文件转换为二进制资源文件,如下所示:

resgen ExampleResources.txt

以下示例提供实例化 ResourceManager 对象的可执行代码,提示用户输入名称并显示问候语。

using System;
using System.Reflection;
using System.Resources;

public class Example1
{
    public static void Main()
    {
        // Retrieve the resource.
        ResourceManager rm = new ResourceManager("ExampleResources",
                                 typeof(Example).Assembly);
        string greeting = rm.GetString("Greeting");

        Console.Write("Enter your name: ");
        string name = Console.ReadLine();
        Console.WriteLine($"{greeting} {name}!");
    }
}
// The example produces output similar to the following:
//       Enter your name: John
//       Hello John!
Imports System.Globalization
Imports System.Reflection
Imports System.Resources

Module Example1
    Public Sub Main()
        ' Retrieve the resource.
        Dim rm As New ResourceManager("ExampleResources",
                                      GetType(Example).Assembly)
        Dim greeting As String = rm.GetString("Greeting")

        Console.Write("Enter your name: ")
        Dim name As String = Console.ReadLine()
        Console.WriteLine("{0} {1}!", greeting, name)
    End Sub
End Module
' The example produces output similar to the following:
'       Enter your name: John
'       Hello John!

可以使用 C# 中的以下命令编译它:

csc Example.cs /resource:ExampleResources.resources

该示例通过将程序集中定义的类型传递给使用 C# 的 typeof 函数或在 Visual Basic 中的 GetType 函数来检索包含资源文件的程序集引用,并获取其 Type.Assembly 属性的值。