Compartir a través de


Métodos System.Resources.ResourceManager.GetObject

En este artículo se proporcionan comentarios adicionales a la documentación de referencia de esta API.

El GetObject método se usa para recuperar recursos que no son de cadena. Estos incluyen valores que pertenecen a tipos de datos primitivos como Int32 o Double, mapas de bits (como un System.Drawing.Bitmap objeto) o objetos serializados personalizados. Normalmente, el objeto devuelto debe convertirse (en C#) o convertirse (en Visual Basic) en un objeto del tipo adecuado.

La IgnoreCase propiedad determina si la comparación de name con los nombres de los recursos no distingue mayúsculas de minúsculas o distingue mayúsculas de minúsculas (el valor predeterminado).

Nota:

Estos métodos pueden producir más excepciones de las enumeradas. Una razón por la que esto puede ocurrir es si un método al que llama este método produce una excepción. Por ejemplo, se podría producir una FileLoadException excepción si se realizó un error al implementar o instalar un ensamblado satélite, o se podría producir una SerializationException excepción si un tipo definido por el usuario produce una excepción definida por el usuario cuando el tipo se deserializa.

Método GetObject(String)

El recurso devuelto se localiza para la referencia cultural de la interfaz de usuario del subproceso actual, que se define mediante la CultureInfo.CurrentUICulture propiedad . Si el recurso no está localizado para esa referencia cultural, el administrador de recursos usa reglas de reserva para cargar un recurso adecuado. Si no se encuentra ningún conjunto utilizable de recursos localizados, ResourceManager se revierte a los recursos de la referencia cultural predeterminada. Si no se encuentra un conjunto de recursos para la referencia cultural predeterminada, el método produce una MissingManifestResourceException excepción o, si se espera que el conjunto de recursos resida en un ensamblado satélite, una MissingSatelliteAssemblyException excepción. Si el administrador de recursos puede cargar un conjunto de recursos adecuado, pero no encuentra un recurso denominado name, el método devuelve null.

Ejemplo

En el siguiente ejemplo se usa el método GetObject(String) para deserializar un objeto personalizado. En el ejemplo se incluye un archivo de código fuente denominado UIElements.cs (UIElements.vb si usa Visual Basic) que define la siguiente estructura denominada PersonTable. Esta estructura está pensada para usarse con una rutina de visualización general de tabla en la que se muestren los nombres localizados de las columnas de la tabla. Tenga en cuenta que la estructura PersonTable está marcada con el atributo 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

El código siguiente de un archivo denominado CreateResources.cs (o CreateResources.vb para Visual Basic) crea un archivo de recursos XML denominado UIResources.resx que almacena un título de tabla y un PersonTable objeto que contiene información para una aplicación localizada para el idioma inglés.

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

El código siguiente de un archivo de código fuente denominado GetObject.cs (o GetObject.vb) recupera los recursos y los muestra en la consola.

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

Puede crear el archivo de recursos y los ensamblados necesarios y ejecutar la aplicación con el siguiente archivo por lotes. Debe usar la opción /r para proporcionar a Resgen.exe una referencia a UIElements.dll para que pueda tener acceso a la información de la estructura PersonTable . Si usa C#, reemplace el nombre del compilador vbc por cscy la extensión .vb por .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

Método GetObject(String, CultureInfo)

El recurso devuelto se localiza para la referencia cultural especificada por culture, o para la referencia cultural especificada por la CultureInfo.CurrentUICulture propiedad si culture es null. Si el recurso no está localizado para esa referencia cultural, el administrador de recursos usa reglas de reserva para cargar un recurso adecuado. Si no se encuentra ningún conjunto utilizable de recursos localizados, el administrador de recursos recurre a los recursos de la referencia cultural predeterminada. Si no se encuentra un conjunto de recursos para la referencia cultural predeterminada, el método produce una MissingManifestResourceException excepción o, si se espera que el conjunto de recursos resida en un ensamblado satélite, una MissingSatelliteAssemblyException excepción. Si el administrador de recursos puede cargar un conjunto de recursos adecuado, pero no encuentra un recurso denominado name, el método devuelve null.

Ejemplo

En el siguiente ejemplo se usa el método GetObject(String, CultureInfo) para deserializar un objeto personalizado. En el ejemplo se incluye un archivo de código fuente denominado NumberInfo.cs (NumberInfo.vb si usa Visual Basic) que define la siguiente estructura denominada Numbers. Esta estructura está pensada para ser utilizada por una aplicación educativa sencilla que enseña a los alumnos que no hablan inglés para contar hasta diez en inglés. Tenga en cuenta que la Numbers clase está marcada con el SerializableAttribute atributo .

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

El siguiente código fuente de un archivo denominado CreateResources.cs (CreateResources.vb para Visual Basic) crea archivos de recursos XML para el idioma inglés predeterminado, así como para los idiomas francés, portugués y ruso.

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

La aplicación siguiente consume los recursos, que establece la referencia cultural actual de la interfaz de usuario en francés (Francia), portugués (Brasil) o ruso (Rusia). Llama al GetObject(String) método para obtener un Numbers objeto que contiene números localizados y el GetObject(String, CultureInfo) método para obtener un Numbers objeto que contiene números de idioma inglés. A continuación, muestra números impares mediante la referencia cultural actual de la interfaz de usuario y el idioma inglés. El archivo de código fuente se denomina 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

Puede usar el siguiente archivo por lotes para compilar y ejecutar la versión de Visual Basic del ejemplo. Si usa C#, reemplace por vbccscy reemplace la .vb extensión por .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

Consideraciones de rendimiento

Si llama al GetObject método varias veces con el mismo name parámetro, no dependa del método que devuelve una referencia al mismo objeto con cada llamada. Esto se debe a que el GetObject método puede devolver una referencia a un objeto de recurso existente en una memoria caché, o bien puede volver a cargar el recurso y devolver una referencia a un nuevo objeto de recurso.