英語で読む

次の方法で共有


System.Resources.ResourceManager.GetObject メソッド

この記事では、この API のリファレンス ドキュメントへの補足的な解説を提供します。

この GetObject メソッドは、文字列以外のリソースを取得するために使用されます。 これには、ビットマップ (オブジェクトなど)、カスタム シリアル化されたオブジェクトなどのInt32Doubleプリミティブ データ型に属する値が含System.Drawing.Bitmapまれます。 通常、返されるオブジェクトは(C#で) キャストするか、(Visual Basic では) 適切な型のオブジェクトに変換する必要があります。

このプロパティは IgnoreCase 、リソース名との比較 name で大文字と小文字が区別されるか、大文字と小文字が区別されるか (既定値) を決定します。

注意

これらのメソッドは、一覧よりも多くの例外をスローする可能性があります。 これが発生する理由の 1 つは、このメソッドが呼び出すメソッドが例外をスローした場合です。 たとえば、サテライト アセンブリの FileLoadException 配置またはインストール中にエラーが発生した場合に例外がスローされる場合や SerializationException 、型が逆シリアル化されるときにユーザー定義型がユーザー定義例外をスローした場合に例外がスローされる場合があります。

GetObject(String) メソッド

返されるリソースは、プロパティによって定義されている現在のスレッドの UI カルチャ用に CultureInfo.CurrentUICulture ローカライズされます。 リソースがそのカルチャにローカライズされていない場合、リソース マネージャーはフォールバック ルールを使用して適切なリソースを読み込みます。 ローカライズされたリソースの使用可能なセットが見つからない場合は、既定の ResourceManager カルチャのリソースにフォールバックします。 既定のカルチャのリソース セットが見つからない場合、メソッドは例外を MissingManifestResourceException スローするか、リソース セットがサテライト アセンブリに存在することが予想される場合は例外を MissingSatelliteAssemblyException スローします。 リソース マネージャーが適切なリソース セットを読み込むことができるが、名前付きの nameリソースが見つからない場合、メソッドは返します null

次の例では、 GetObject(String) メソッドを使用して、カスタム オブジェクトを逆シリアル化します。 この例には、UIElements.cs PersonTableという名前のソース コード ファイルが含まれています (Visual Basic を使用している場合はUIElements.vb)。 この構造体は、ローカライズされたテーブル列名を表示する一般的なテーブル表示ルーチンでの使用を目的としています。 PersonTable 構造体は、 SerializableAttribute 属性でマークされています。

C#
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;
   }
}

CreateResources.cs (または Visual Basic の場合は CreateResources.vb) という名前のファイルの次のコードは、テーブル タイトルと PersonTable 、英語用にローカライズされたアプリの情報を含むオブジェクトを格納する UIResources.resx という名前の XML リソース ファイルを作成します。

C#
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();
   }
}

GetObject.cs (またはGetObject.vb) という名前のソース コード ファイル内の次のコードは、リソースを取得してコンソールに表示します。

C#
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();
   }
}

次のバッチ ファイルを実行することで、必要なリソース ファイルとアセンブリをビルドし、アプリケーションを実行することができます。 /r 構造体に関する情報にアクセスできるように、 PersonTable オプションを使用して Resgen.exe を指定し、UIElements.dll への参照を含める必要があります。 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

返されるリソースは、指定されたカルチャ、またはプロパティでculture指定されているカルチャに対してCultureInfo.CurrentUICultureローカライズされます (指定されている場合culture)。null リソースがそのカルチャにローカライズされていない場合、リソース マネージャーはフォールバック ルールを使用して適切なリソースを読み込みます。 ローカライズされたリソースの使用可能なセットが見つからない場合、リソース マネージャーは既定のカルチャのリソースにフォールバックします。 既定のカルチャのリソース セットが見つからない場合、メソッドは例外を MissingManifestResourceException スローするか、リソース セットがサテライト アセンブリに存在することが予想される場合は例外を MissingSatelliteAssemblyException スローします。 リソース マネージャーが適切なリソース セットを読み込むことができるが、名前付きの nameリソースが見つからない場合、メソッドは返します null

次の例では、 GetObject(String, CultureInfo) メソッドを使用して、カスタム オブジェクトを逆シリアル化します。 この例には、NumberInfo.cs Numbersという名前のソース コード ファイルが含まれています (Visual Basic を使用している場合はNumberInfo.vb)。 この構造は、英語以外の学生が英語で10にカウントするように教える簡単な教育アプリによって使用されることを意図しています。 クラスは Numbers 属性でマークされていることに SerializableAttribute 注意してください。

C#
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;                                    
   }                  
}

CreateResources.cs (Visual Basic のCreateResources.vb) という名前のファイルの次のソース コードは、既定の英語とフランス語、ポルトガル語、ロシア語の XML リソース ファイルを作成します。

C#
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();    
   }
}

リソースは次のアプリによって消費されます。このアプリでは、現在の UI カルチャがフランス語 (フランス)、ポルトガル語 (ブラジル)、ロシア語 (ロシア) に設定されます。 このメソッドを GetObject(String) 呼び出して、 Numbers ローカライズされた番号を含むオブジェクトを取得し、 GetObject(String, CultureInfo) 英語の言語番号を含むオブジェクトを Numbers 取得するメソッドを呼び出します。 次に、現在の UI カルチャと英語を使用して奇数を表示します。 ソース コード ファイルの名前は ShowNumbers.cs (ShowNumbers.vb) です。

C#
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

次のバッチ ファイルを使用して、この例の Visual Basic バージョンをビルドして実行できます。 C# を使用している場合は、次のようにcsc置き換えvbc、拡張機能.cs.vb .

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 既存のリソース オブジェクトへの参照を返すことができるか、リソースを再読み込みして新しいリソース オブジェクトへの参照を返すことができるためです。