共用方式為


System.Resources.ResourceManager.GetObject 方法

本文提供此 API 參考文件的補充備註。

方法 GetObject 可用來擷取非字串資源。 這些值包括屬於基本數據類型的值,例如 Int32Double、點陣圖(例如 System.Drawing.Bitmap 物件),或自定義串行化物件。 一般而言,傳回的對象必須轉換成適當類型的物件(在 C#中)或轉換(在 Visual Basic 中)。

屬性 IgnoreCase 會判斷 與資源名稱的比較 name 是否不區分大小寫或區分大小寫 (預設值)。

注意

這些方法可能會擲回比列出的更多例外狀況。 發生這種狀況的其中一個原因是此方法所呼叫的方法擲回例外狀況。 例如, FileLoadException 如果部署或安裝附屬元件時發生錯誤, SerializationException 或如果使用者定義類型在還原串行化時擲回使用者定義例外狀況,可能會擲回例外狀況。

GetObject(String) 方法

傳回的資源會針對目前線程的UI文化特性進行當地語系化,而這個文化特性是由 CultureInfo.CurrentUICulture 屬性所定義。 如果資源未針對該文化特性進行當地語系化,資源管理員會使用後援規則來載入適當的資源。 如果找不到一組可使用的當地語系化資源,則會 ResourceManager 回復預設文化特性的資源。 如果找不到預設文化特性的資源集,此方法會 MissingManifestResourceException 擲回例外狀況,或者,如果預期資源集位於附屬元件中,則為 MissingSatelliteAssemblyException 例外狀況。 如果資源管理員可以載入適當的資源集,但找不到名為 name的資源,此方法會傳 null回 。

範例

下列範例使用 GetObject(String) 方法來還原序列化自訂物件。 此範例包含名為 UIElements.cs 的原始程式碼檔案(如果您使用 Visual Basic,則為 UIElements.vb),其定義名為 PersonTable的下列結構。 此結構是為了供一般資料表顯示常式使用,以顯示資料表資料行的當地語系化名稱。 請注意,PersonTable 結構會以 SerializableAttribute 屬性標記。

using System;

[Serializable] public struct PersonTable
{
   public readonly int nColumns;
   public readonly string column1;
   public readonly string column2;
   public readonly string column3;
   public readonly int width1;
   public readonly int width2;
   public readonly int width3;

   public PersonTable(string column1, string column2, string column3,
                  int width1, int width2, int width3)
   {
      this.column1 = column1;
      this.column2 = column2;
      this.column3 = column3;
      this.width1 = width1;
      this.width2 = width2;
      this.width3 = width3;
      this.nColumns = typeof(PersonTable).GetFields().Length / 2;
   }
}
<Serializable> Public Structure PersonTable1
    Public ReadOnly nColumns As Integer
    Public ReadOnly column1 As String
    Public ReadOnly column2 As String
    Public ReadOnly column3 As String
    Public ReadOnly width1 As Integer
    Public ReadOnly width2 As Integer
    Public ReadOnly width3 As Integer

    Public Sub New(column1 As String, column2 As String, column3 As String,
                  width1 As Integer, width2 As Integer, width3 As Integer)
        Me.column1 = column1
        Me.column2 = column2
        Me.column3 = column3
        Me.width1 = width1
        Me.width2 = width2
        Me.width3 = width3
        Me.nColumns = Me.GetType().GetFields().Count \ 2
    End Sub
End Structure

下列程式代碼來自名為 CreateResources.cs 的檔案(或 Visual Basic 的 CreateResources.vb),會建立名為 UIResources.resx 的 XML 資源檔,其中儲存數據表標題和 PersonTable 物件,其中包含當地語系化為英文語言之應用程式的資訊。

using System;
using System.Resources;

public class CreateResource
{
   public static void Main()
   {
      PersonTable table = new PersonTable("Name", "Employee Number",
                                          "Age", 30, 18, 5);
      ResXResourceWriter rr = new ResXResourceWriter(@".\UIResources.resx");
      rr.AddResource("TableName", "Employees of Acme Corporation");
      rr.AddResource("Employees", table);
      rr.Generate();
      rr.Close();
   }
}
Imports System.Resources

Module CreateResource1
    Public Sub Main()
        Dim table As New PersonTable("Name", "Employee Number", "Age", 30, 18, 5)
        Dim rr As New ResXResourceWriter(".\UIResources.resx")
        rr.AddResource("TableName", "Employees of Acme Corporation")
        rr.AddResource("Employees", table)
        rr.Generate()
        rr.Close()
    End Sub
End Module

在名為 GetObject.cs 的原始程式碼檔案中,下列程式代碼會 GetObject.vb擷取資源,並將其顯示至控制台。

using System;
using System.Resources;

[assembly: NeutralResourcesLanguageAttribute("en")]

public class Example3
{
   public static void Main()
   {
      string fmtString = String.Empty;
      ResourceManager rm = new ResourceManager("UIResources", typeof(Example).Assembly);
      string title = rm.GetString("TableName");
      PersonTable tableInfo = (PersonTable) rm.GetObject("Employees");

      if (! String.IsNullOrEmpty(title)) {
         fmtString = "{0," + ((Console.WindowWidth + title.Length) / 2).ToString() + "}";
         Console.WriteLine(fmtString, title);
         Console.WriteLine();
      }

      for (int ctr = 1; ctr <= tableInfo.nColumns; ctr++) {
         string columnName = "column"  + ctr.ToString();
         string widthName = "width" + ctr.ToString();
         string value = tableInfo.GetType().GetField(columnName).GetValue(tableInfo).ToString();
         int width = (int) tableInfo.GetType().GetField(widthName).GetValue(tableInfo);
         fmtString = "{0,-" + width.ToString() + "}";
         Console.Write(fmtString, value);
      }
      Console.WriteLine();
   }
}
Imports System.Resources

<Assembly: NeutralResourcesLanguageAttribute("en")>

Module Example
   Public Sub Main()
      Dim fmtString As String = String.Empty
      Dim rm As New ResourceManager("UIResources", GetType(Example).Assembly)       
      Dim title As String = rm.GetString("TableName")
      Dim tableInfo As PersonTable = DirectCast(rm.GetObject("Employees"), PersonTable)

      If Not String.IsNullOrEmpty(title) Then
         fmtString = "{0," + ((Console.WindowWidth + title.Length) \ 2).ToString() + "}" 
         Console.WriteLine(fmtString, title)      
         Console.WriteLine()
      End If

      For ctr As Integer = 1 To tableInfo.nColumns
         Dim columnName As String = "column"  + ctr.ToString()
         Dim widthName As String = "width" + ctr.ToString()
         Dim value As String = CStr(tableInfo.GetType().GetField(columnName).GetValue(tableInfo))
         Dim width As Integer = CInt(tableInfo.GetType().GetField(widthName).GetValue(tableInfo))
         fmtString = "{0,-" + width.ToString() + "}"
         Console.Write(fmtString, value)
      Next      
      Console.WriteLine()
   End Sub
End Module

您可以建立必要的資源檔和組件,並藉由執行下列批次檔來執行應用程式。 您必須使用 /r 選項將 UIElements.dll 的參考提供給 Resgen.exe,使其可以存取有關 PersonTable 結構的資訊。 如果使用 C#,請將 vbc 編譯器名稱取代成 csc,並將 .vb 副檔名取代成 .cs

vbc /t:library UIElements.vb
vbc CreateResources.vb /r:UIElements.dll
CreateResources

resgen UIResources.resx  /r:UIElements.dll
vbc GetObject.vb /r:UIElements.dll /resource:UIResources.resources

GetObject.exe

GetObject(String, CultureInfo) 方法

傳回的資源會針對 所culture指定的文化特性進行當地語系化,如果 為 ,則為 屬性culturenullCultureInfo.CurrentUICulture指定的文化特性。 如果資源未針對該文化特性進行當地語系化,資源管理員會使用後援規則來載入適當的資源。 如果找不到一組可使用的當地語系化資源,資源管理員會回復預設文化特性的資源。 如果找不到預設文化特性的資源集,此方法會 MissingManifestResourceException 擲回例外狀況,或者,如果預期資源集位於附屬元件中,則為 MissingSatelliteAssemblyException 例外狀況。 如果資源管理員可以載入適當的資源集,但找不到名為 name的資源,此方法會傳 null回 。

範例

下列範例使用 GetObject(String, CultureInfo) 方法來還原序列化自訂物件。 此範例包含名為 NumberInfo.cs 的原始程式碼檔案(如果您使用 Visual Basic NumberInfo.vb),其定義名為 Numbers的下列結構。 此結構旨在由簡單的教育應用程式使用,該應用程式會教導非英語學生計算為十分之一的英文。 請注意,類別 Numbers 會以 SerializableAttribute 屬性標示。

using System;

[Serializable] public class Numbers2
{
   public readonly string One;
   public readonly string Two;
   public readonly string Three;
   public readonly string Four;
   public readonly string Five;
   public readonly string Six;
   public readonly string Seven;
   public readonly string Eight;
   public readonly string Nine;
   public readonly string Ten;

   public Numbers2(string one, string two, string three, string four, 
                  string five, string six, string seven, string eight,
                  string nine, string ten)
   {                     
      this.One = one;
      this.Two = two;
      this.Three = three;
      this.Four = four;
      this.Five = five;
      this.Six = six;
      this.Seven = seven;
      this.Eight = eight;
      this.Nine = nine;
      this.Ten = ten;                                    
   }                  
}
<Serializable> Public Class Numbers2
    Public ReadOnly One As String
    Public ReadOnly Two As String
    Public ReadOnly Three As String
    Public ReadOnly Four As String
    Public ReadOnly Five As String
    Public ReadOnly Six As String
    Public ReadOnly Seven As String
    Public ReadOnly Eight As String
    Public ReadOnly Nine As String
    Public ReadOnly Ten As String

    Public Sub New(one As String, two As String, three As String, four As String,
                   five As String, six As String, seven As String, eight As String,
                   nine As String, ten As String)
        Me.One = one
        Me.Two = two
        Me.Three = three
        Me.Four = four
        Me.Five = five
        Me.Six = six
        Me.Seven = seven
        Me.Eight = eight
        Me.Nine = nine
        Me.Ten = ten
    End Sub
End Class

下列來自名為 CreateResources.cs 的檔案原始程式碼 (CreateResources.vb for Visual Basic) 會建立預設英文的 XML 資源檔,以及法文、葡萄牙文和俄文語言。

using System;
using System.Resources;

public class CreateResource
{
   public static void Main()
   {
      Numbers en = new Numbers("one", "two", "three", "four", "five",
                               "six", "seven", "eight", "nine", "ten");
      CreateResourceFile(en, "en");
      Numbers fr = new Numbers("un", "deux", "trois", "quatre", "cinq", 
                               "six", "sept", "huit", "neuf", "dix");
      CreateResourceFile(fr, "fr");
      Numbers pt = new Numbers("um", "dois", "três", "quatro", "cinco", 
                               "seis", "sete", "oito", "nove", "dez");
      CreateResourceFile(pt, "pt"); 
      Numbers ru = new Numbers("один", "два", "три", "четыре", "пять", 
                               "шесть", "семь", "восемь", "девять", "десять");                                                       
      CreateResourceFile(ru, "ru");
   }

   public static void CreateResourceFile(Numbers n, string lang)
   {
      string filename = @".\NumberResources" + 
                        (lang != "en" ? "." + lang : "" ) +
                        ".resx";
      ResXResourceWriter rr = new ResXResourceWriter(filename);
      rr.AddResource("Numbers", n);
      rr.Generate();
      rr.Close();    
   }
}
Imports System.Resources

Module CreateResource
   Public Sub Main()
      Dim en As New Numbers("one", "two", "three", "four", "five",
                            "six", "seven", "eight", "nine", "ten")
      CreateResourceFile(en, "en")
      Dim fr As New Numbers("un", "deux", "trois", "quatre", "cinq", 
                            "six", "sept", "huit", "neuf", "dix")
      CreateResourceFile(fr, "fr")
      Dim pt As New Numbers("um", "dois", "três", "quatro", "cinco", 
                            "seis", "sete", "oito", "nove", "dez")
      CreateResourceFile(pt, "pt") 
      Dim ru As New Numbers("один", "два", "три", "четыре", "пять", 
                            "шесть", "семь", "восемь", "девять", "десять")                                                       
      CreateResourceFile(ru, "ru")
   End Sub

   Public Sub CreateResourceFile(n As Numbers, lang As String)
      Dim filename As String = ".\NumberResources" + 
                               If(lang <> "en", "." + lang, "") +
                               ".resx"
      Dim rr As New ResXResourceWriter(filename)
      rr.AddResource("Numbers", n)
      rr.Generate()
      rr.Close()    
   End Sub
End Module

下列應用程式會耗用資源,其會將目前的UI文化特性設定為法文(法國)、葡萄牙文(巴西)或俄羅斯(俄羅斯)。 它會呼叫 GetObject(String) 方法以取得 Numbers 包含當地語系化數位的物件,以及 GetObject(String, CultureInfo) 取得 Numbers 包含英文語言數字的物件。 然後,它會使用目前的UI文化特性和英文顯示奇數。 原始碼檔案名為 ShowNumbers.cs (ShowNumbers.vb)。

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

[assembly:NeutralResourcesLanguageAttribute("en-US")]

public class Example
{
   static string[] cultureNames = [ "fr-FR", "pt-BR", "ru-RU" ];

   public static void Main()
   {
      // Make any non-default culture the current culture.
      Random rnd = new Random();
      CultureInfo culture = CultureInfo.CreateSpecificCulture(cultureNames[rnd.Next(0, cultureNames.Length)]);
      Thread.CurrentThread.CurrentUICulture = culture;
      Console.WriteLine("The current culture is {0}\n", CultureInfo.CurrentUICulture.Name);
      CultureInfo enCulture = CultureInfo.CreateSpecificCulture("en-US");

      ResourceManager rm = new ResourceManager(typeof(NumberResources));
      Numbers numbers = (Numbers) rm.GetObject("Numbers");
      Numbers numbersEn = (Numbers) rm.GetObject("Numbers", enCulture);
      Console.WriteLine("{0} --> {1}", numbers.One, numbersEn.One);
      Console.WriteLine("{0} --> {1}", numbers.Three, numbersEn.Three);
      Console.WriteLine("{0} --> {1}", numbers.Five, numbersEn.Five);
      Console.WriteLine("{0} --> {1}", numbers.Seven, numbersEn.Seven);
      Console.WriteLine("{0} --> {1}\n", numbers.Nine, numbersEn.Nine);
   }
}

internal class NumberResources
{
}
// The example displays output like the following:
//       The current culture is pt-BR
//
//       um --> one
//       três --> three
//       cinco --> five
//       sete --> seven
//       nove --> nine
Imports System.Globalization
Imports System.Resources
Imports System.Threading

Module Example2
    Dim cultureNames() As String = {"fr-FR", "pt-BR", "ru-RU"}

    Public Sub Main()
        ' Make any non-default culture the current culture.
        Dim rnd As New Random
        Dim culture As CultureInfo = CultureInfo.CreateSpecificCulture(cultureNames(rnd.Next(0, cultureNames.Length)))
        Thread.CurrentThread.CurrentUICulture = culture
        Console.WriteLine("The current culture is {0}", CultureInfo.CurrentUICulture.Name)
        Console.WriteLine()
        Dim enCulture As CultureInfo = CultureInfo.CreateSpecificCulture("en-US")

        Dim rm As New ResourceManager(GetType(NumberResources))
        Dim numbers As Numbers = CType(rm.GetObject("Numbers"), Numbers)
        Dim numbersEn As Numbers = CType(rm.GetObject("Numbers", enCulture), Numbers)
        Console.WriteLine("{0} --> {1}", numbers.One, numbersEn.One)
        Console.WriteLine("{0} --> {1}", numbers.Three, numbersEn.Three)
        Console.WriteLine("{0} --> {1}", numbers.Five, numbersEn.Five)
        Console.WriteLine("{0} --> {1}", numbers.Seven, numbersEn.Seven)
        Console.WriteLine("{0} --> {1}", numbers.Nine, numbersEn.Nine)
        Console.WriteLine()
    End Sub
End Module


Friend Class NumberResources
End Class

' The example displays output like the following:
'       The current culture is pt-BR
'       
'       um --> one
'       três --> three
'       cinco --> five
'       sete --> seven
'       nove --> nine

您可以使用下列批處理檔來建置和執行範例的 Visual Basic 版本。 如果您使用 C#,請將 取代 vbccsc,並將延伸模組取代 .vb.cs

vbc /t:library NumberInfo.vb

vbc CreateResources.vb /r:NumberInfo.dll
CreateResources

resgen NumberResources.resx /r:NumberInfo.dll

resgen NumberResources.fr.resx /r:Numberinfo.dll
Md fr
al /embed:NumberResources.fr.resources /culture:fr /t:lib /out:fr\ShowNumbers.resources.dll

resgen NumberResources.pt.resx  /r:Numberinfo.dll
Md pt
al /embed:NumberResources.pt.resources /culture:pt /t:lib /out:pt\ShowNumbers.resources.dll

resgen NumberResources.ru.resx /r:Numberinfo.dll
Md ru
al /embed:NumberResources.ru.resources /culture:ru /t:lib /out:ru\ShowNumbers.resources.dll

vbc ShowNumbers.vb /r:NumberInfo.dll /resource:NumberResources.resources
ShowNumbers.exe

效能考量

如果您使用相同的name參數多次呼叫 GetObject 方法,則不要相依於方法,而每個呼叫都會傳回相同對象的參考。 這是因為 GetObject 方法可以傳回快取中現有資源對象的參考,也可以重載資源,並傳回新資源對象的參考。