Methoden voor System.Resources.ResourceManager.GetObject

Notitie

In dit artikel vindt u aanvullende opmerkingen in de referentiedocumentatie voor deze API.

De methode GetObject wordt gebruikt om niet-tekenreeksbronnen op te halen. Dit zijn waarden die deel uitmaken van primitieve gegevenstypen, zoals Int32 of Double, bitmaps (zoals een System.Drawing.Bitmap object) of aangepaste geserialiseerde objecten. Normaal gesproken moet het geretourneerde object worden gecast (in C#) of worden geconverteerd (in Visual Basic) naar een object van het juiste type.

De eigenschap IgnoreCase bepaalt of de vergelijking van de namen van resources met name hoofdletterongevoelig of hoofdlettergevoelig (de standaardinstelling) is.

Notitie

Deze methoden kunnen meer uitzonderingen genereren dan worden vermeld. Een reden waarom dit kan gebeuren, is dat een methode waarop deze methode een beroep doet, een uitzondering werpt. Er kan bijvoorbeeld een FileLoadException uitzondering optreden als er een fout is opgetreden bij het implementeren of installeren van een satellietassembly, of een SerializationException uitzondering kan worden gegenereerd als een door de gebruiker gedefinieerd type een door de gebruiker gedefinieerde uitzondering genereert wanneer het type wordt gedeserialiseerd.

GetObject(String) methode

De geretourneerde resource is gelokaliseerd voor de UI-cultuur van de huidige thread, die wordt gedefinieerd door de eigenschap CultureInfo.CurrentUICulture. Als de resource niet is gelokaliseerd voor die cultuur, gebruikt resourcemanager terugvalregels om een geschikte resource te laden. Als er geen bruikbare set gelokaliseerde resources wordt gevonden, gebruikt de ResourceManager de resources van de standaardcultuur. Als een resourceset voor de standaardcultuur niet wordt gevonden, genereert de methode een MissingManifestResourceException uitzondering of, als de resourceset naar verwachting zich in een satellietassembly bevindt, een MissingSatelliteAssemblyException uitzondering. Als de resourcemanager een juiste resourceset kan laden maar geen resource met de naam namekan vinden, retourneert de methode null.

Voorbeeld

In het volgende voorbeeld wordt de methode GetObject(String) gebruikt om een aangepast object te deserialiseren. Het voorbeeld bevat een broncodebestand met de naam UIElements.cs (UIElements.vb als u Visual Basic gebruikt) waarmee de volgende structuur met de naam PersonTablewordt gedefinieerd. Deze structuur is bedoeld om te worden gebruikt door een algemene tabelweergaveroutine waarmee de gelokaliseerde namen van tabelkolommen worden weergegeven. Houd er rekening mee dat de PersonTable structuur is gemarkeerd met het kenmerk 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

Met de volgende code van een bestand met de naam CreateResources.cs (of CreateResources.vb voor Visual Basic) wordt een XML-resourcebestand met de naam UIResources.resx gemaakt waarin een tabeltitel en een PersonTable-object worden opgeslagen dat informatie bevat voor een app die is gelokaliseerd voor de Engelse taal.

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

Met de volgende code in een broncodebestand met de naam GetObject.cs (of GetObject.vb) worden de resources opgehaald en weergegeven in de console.

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

U kunt het benodigde resourcebestand en de benodigde assembly's bouwen en de app uitvoeren door het volgende batchbestand uit te voeren. U moet de /r optie gebruiken om Resgen.exe op te geven met een verwijzing naar UIElements.dll, zodat deze toegang heeft tot informatie over de PersonTable structuur. Als u C# gebruikt, vervangt u de naam van de vbc compiler door cscen vervangt u de .vb-extensie door .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) methode

De geretourneerde bron is gelokaliseerd voor de cultuur die is opgegeven door culture, of voor de cultuur die is gespecificeerd door de eigenschap CultureInfo.CurrentUICulture indien culture gelijk is aan null. Als de resource niet is gelokaliseerd voor die cultuur, gebruikt resourcemanager terugvalregels om een geschikte resource te laden. Als er geen bruikbare set gelokaliseerde resources wordt gevonden, valt de resourcemanager terug op de standaardresources van de cultuur. Als een resourceset voor de standaardcultuur niet wordt gevonden, genereert de methode een MissingManifestResourceException uitzondering of, als de resourceset naar verwachting zich in een satellietassembly bevindt, een MissingSatelliteAssemblyException uitzondering. Als de resourcemanager een juiste resourceset kan laden maar geen resource met de naam namekan vinden, retourneert de methode null.

Voorbeeld

In het volgende voorbeeld wordt de methode GetObject(String, CultureInfo) gebruikt om een aangepast object te deserialiseren. Het voorbeeld bevat een broncodebestand met de naam NumberInfo.cs (NumberInfo.vb als u Visual Basic gebruikt) waarmee de volgende structuur met de naam Numberswordt gedefinieerd. Deze structuur is bedoeld om te worden gebruikt door een eenvoudige educatieve app die niet-Engels sprekende leerlingen/studenten leert te tellen tot tien in het Engels. Houd er rekening mee dat de klasse Numbers is gemarkeerd met het kenmerk 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

Met de volgende broncode van een bestand met de naam CreateResources.cs (CreateResources.vb voor Visual Basic) worden XML-bronbestanden gemaakt voor de standaardTaal Engels, evenals voor de Franse, Portugese en Russische talen.

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

De resources worden gebruikt door de volgende app, waarmee de huidige UI-cultuur wordt ingesteld op Frans (Frankrijk), Portugees (Brazilië) of Russisch (Rusland). Hiermee wordt de methode GetObject(String) aangeroepen om een Numbers-object op te halen dat gelokaliseerde getallen bevat en de methode GetObject(String, CultureInfo) om een Numbers-object op te halen dat Engelse taalnummers bevat. Vervolgens worden oneven getallen weergegeven met behulp van de huidige UI-cultuur en de Engelse taal. Het broncodebestand heet 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 {CultureInfo.CurrentUICulture.Name}\n");
      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($"{numbers.One} --> {numbersEn.One}");
      Console.WriteLine($"{numbers.Three} --> {numbersEn.Three}");
      Console.WriteLine($"{numbers.Five} --> {numbersEn.Five}");
      Console.WriteLine($"{numbers.Seven} --> {numbersEn.Seven}");
      Console.WriteLine($"{numbers.Nine} --> {numbersEn.Nine}\n");
   }
}

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

U kunt het volgende batchbestand gebruiken om de Visual Basic-versie van het voorbeeld te bouwen en uit te voeren. Als u C# gebruikt, vervangt u vbc door cscen vervangt u de .vb-extensie door .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

Prestatieoverwegingen

Als u de methode GetObject meerdere keren aanroept met dezelfde parameter name, is dit niet afhankelijk van de methode die bij elke aanroep een verwijzing naar hetzelfde object retourneert. Dit komt doordat de methode GetObject een verwijzing naar een bestaand resourceobject in een cache kan retourneren of de resource opnieuw kan laden en een verwijzing naar een nieuw resourceobject kan retourneren.