Metodi System.Resources.ResourceManager.GetObject
Questo articolo fornisce osservazioni supplementari alla documentazione di riferimento per questa API.
Il GetObject metodo viene usato per recuperare risorse non stringa. Questi includono valori che appartengono a tipi di dati primitivi, Int32 ad esempio o Double, bitmap (ad esempio un System.Drawing.Bitmap oggetto) o oggetti serializzati personalizzati. In genere, l'oggetto restituito deve essere sottoposto a cast (in C#) o convertito (in Visual Basic) in un oggetto del tipo appropriato.
La IgnoreCase proprietà determina se il confronto tra name
i nomi delle risorse non fa distinzione tra maiuscole e minuscole o distinzione tra maiuscole e minuscole (impostazione predefinita).
Nota
Questi metodi possono generare più eccezioni di quelle elencate. Un motivo per cui questo problema può verificarsi è se un metodo che chiama questo metodo genera un'eccezione. Ad esempio, potrebbe essere generata un'eccezione FileLoadException se è stato generato un errore durante la distribuzione o l'installazione di un assembly satellite oppure SerializationException se un tipo definito dall'utente genera un'eccezione definita dall'utente quando il tipo viene deserializzato.
Metodo GetObject(String)
La risorsa restituita viene localizzata per le impostazioni cultura dell'interfaccia utente del thread corrente, definito dalla CultureInfo.CurrentUICulture proprietà . Se la risorsa non è localizzata per tali impostazioni cultura, gestione risorse usa regole di fallback per caricare una risorsa appropriata. Se non viene trovato alcun set utilizzabile di risorse localizzate, esegue il ResourceManager fallback sulle risorse delle impostazioni cultura predefinite. Se non viene trovato un set di risorse per le impostazioni cultura predefinite, il metodo genera un'eccezione MissingManifestResourceException o, se si prevede che il set di risorse risieda in un assembly satellite, un'eccezione MissingSatelliteAssemblyException . Se resource manager può caricare un set di risorse appropriato ma non riesce a trovare una risorsa denominata name
, il metodo restituisce null
.
Esempio
Nell'esempio seguente viene usato il metodo GetObject(String) per deserializzare un oggetto personalizzato. L'esempio include un file di codice sorgente denominato UIElements.cs (UIElements.vb se si usa Visual Basic) che definisce la struttura seguente denominata PersonTable
. Questa struttura deve essere usata da una procedura generale di visualizzazione della tabella che mostra i nomi localizzati delle colonne della tabella. Si noti che la struttura PersonTable
è contrassegnata con l'attributo 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
Il codice seguente da un file denominato CreateResources.cs (o CreateResources.vb per Visual Basic) crea un file di risorse XML denominato UIResources.resx che archivia un titolo di tabella e un PersonTable
oggetto contenente informazioni per un'app localizzata per la lingua inglese.
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
Il codice seguente in un file di codice sorgente denominato GetObject.cs (o GetObject.vb) recupera le risorse e le visualizza nella 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
È possibile creare il file di risorse e gli assembly necessari ed eseguire l'app mediante il file batch seguente. È necessario usare l'opzione /r
per fornire a Resgen.exe un riferimento a UIElements.dll in modo che possa accedere alle informazioni sulla struttura PersonTable
. Se si usa C#, sostituire il nome del compilatore vbc
con csc
e l'estensione .vb
con .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
Metodo GetObject(String, CultureInfo)
La risorsa restituita viene localizzata per le impostazioni cultura specificate da culture
o per le impostazioni cultura specificate dalla CultureInfo.CurrentUICulture proprietà se culture
è null
. Se la risorsa non è localizzata per tali impostazioni cultura, gestione risorse usa regole di fallback per caricare una risorsa appropriata. Se non viene trovato alcun set utilizzabile di risorse localizzate, resource manager esegue il fallback sulle risorse delle impostazioni cultura predefinite. Se non viene trovato un set di risorse per le impostazioni cultura predefinite, il metodo genera un'eccezione MissingManifestResourceException o, se si prevede che il set di risorse risieda in un assembly satellite, un'eccezione MissingSatelliteAssemblyException . Se resource manager può caricare un set di risorse appropriato ma non riesce a trovare una risorsa denominata name
, il metodo restituisce null
.
Esempio
Nell'esempio seguente viene usato il metodo GetObject(String, CultureInfo) per deserializzare un oggetto personalizzato. L'esempio include un file di codice sorgente denominato NumberInfo.cs (NumberInfo.vb se si usa Visual Basic) che definisce la struttura seguente denominata Numbers
. Questa struttura è progettata per essere usata da una semplice app educativa che insegna agli studenti che parlano non inglese di contare su dieci in inglese. Si noti che la Numbers
classe è contrassegnata con l'attributo 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
Il codice sorgente seguente da un file denominato CreateResources.cs (CreateResources.vb per Visual Basic) crea file di risorse XML per la lingua inglese predefinita, nonché per le lingue francese, portoghese e russo.
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
Le risorse vengono utilizzate dall'app seguente, che imposta le impostazioni cultura correnti dell'interfaccia utente su Francese (Francia), Portoghese (Brasile) o Russo (Russia). Chiama il GetObject(String) metodo per ottenere un Numbers
oggetto contenente numeri localizzati e il GetObject(String, CultureInfo) metodo per ottenere un Numbers
oggetto contenente numeri di lingua inglese. Visualizza quindi numeri dispari usando le impostazioni cultura correnti dell'interfaccia utente e la lingua inglese. Il file di codice sorgente è denominato 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
È possibile usare il file batch seguente per compilare ed eseguire la versione di Visual Basic dell'esempio. Se si usa C#, sostituire vbc
con csc
e sostituire l'estensione .vb
con .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
Considerazioni sulle prestazioni
Se si chiama il GetObject metodo più volte con lo stesso name
parametro, non dipende dal metodo che restituisce un riferimento allo stesso oggetto con ogni chiamata. Questo perché il GetObject metodo può restituire un riferimento a un oggetto risorsa esistente in una cache oppure ricaricare la risorsa e restituire un riferimento a un nuovo oggetto risorsa.