Odpowiedzi:
Należy zawsze używać menedżera zasobów i nie czytać plików bezpośrednio, aby mieć pewność, że brana jest pod uwagę globalizacja.
using System.Collections;
using System.Globalization;
using System.Resources;
...
/* Reference to your resources class -- may be named differently in your case */
ResourceManager MyResourceClass =
new ResourceManager(typeof(Resources));
ResourceSet resourceSet =
MyResourceClass.ResourceManager.GetResourceSet(CultureInfo.CurrentUICulture, true, true);
foreach (DictionaryEntry entry in resourceSet)
{
string resourceKey = entry.Key.ToString();
object resource = entry.Value;
}
ResourceManager MyResourceClass = new ResourceManager("Resources.ResourceFileName", System.Reflection.Assembly.Load("App_GlobalResources"));
Blogowałem o tym na swoim blogu :) Krótka wersja to, aby znaleźć pełne nazwy zasobów (chyba, że już je znasz):
var assembly = Assembly.GetExecutingAssembly();
foreach (var resourceName in assembly.GetManifestResourceNames())
System.Console.WriteLine(resourceName);
Aby użyć ich wszystkich do czegoś:
foreach (var resourceName in assembly.GetManifestResourceNames())
{
using(var stream = assembly.GetManifestResourceStream(resourceName))
{
// Do something with stream
}
}
Aby użyć zasobów w innych zestawach niż wykonujący, wystarczy uzyskać inny obiekt zestawu przy użyciu niektórych innych metod statycznych Assembly
klasy. Mam nadzieję, że to pomoże :)
ResXResourceReader rsxr = new ResXResourceReader("your resource file path");
// Iterate through the resources and display the contents to the console.
foreach (DictionaryEntry d in rsxr)
{
Console.WriteLine(d.Key.ToString() + ":\t" + d.Value.ToString());
}
// Create a ResXResourceReader for the file items.resx.
ResXResourceReader rsxr = new ResXResourceReader("items.resx");
// Create an IDictionaryEnumerator to iterate through the resources.
IDictionaryEnumerator id = rsxr.GetEnumerator();
// Iterate through the resources and display the contents to the console.
foreach (DictionaryEntry d in rsxr)
{
Console.WriteLine(d.Key.ToString() + ":\t" + d.Value.ToString());
}
//Close the reader.
rsxr.Close();
zobacz link: przykład firmy Microsoft
System.Windows.Forms
zestawie i nie jest automatycznie dodawana, jeśli używasz aplikacji MVC
W chwili dodania pliku .RESX zasobu do projektu program Visual Studio utworzy plik Designer.cs o tej samej nazwie, tworząc dla Ciebie klasę ze wszystkimi elementami zasobu jako właściwościami statycznymi. Wszystkie nazwy zasobów można wyświetlić, wpisując kropkę w edytorze po wpisaniu nazwy pliku zasobów.
Alternatywnie możesz użyć odbicia, aby zapętlić te nazwy.
Type resourceType = Type.GetType("AssemblyName.Resource1");
PropertyInfo[] resourceProps = resourceType.GetProperties(
BindingFlags.NonPublic |
BindingFlags.Static |
BindingFlags.GetProperty);
foreach (PropertyInfo info in resourceProps)
{
string name = info.Name;
object value = info.GetValue(null, null); // object can be an image, a string whatever
// do something with name and value
}
Ta metoda jest oczywiście używana tylko wtedy, gdy plik RESX znajduje się w zakresie bieżącego zestawu lub projektu. W przeciwnym razie użyj metody zapewnianej przez „puls”.
Zaletą tej metody jest to, że wywołujesz rzeczywiste właściwości, które zostały dla Ciebie dostarczone, biorąc pod uwagę dowolną lokalizację, jeśli chcesz. Jest to jednak raczej zbędne, ponieważ normalnie powinieneś używać bezpośredniej metody typu safe do wywoływania właściwości zasobów.
Możesz użyć ResourceManager.GetResourceSet .
Jeśli chcesz używać LINQ, użyj resourceSet.OfType<DictionaryEntry>()
. Korzystanie z LINQ pozwala na przykład wybierać zasoby na podstawie ich indeksu (int) zamiast klucza (string):
ResourceSet resourceSet = Resources.ResourceManager.GetResourceSet(CultureInfo.CurrentUICulture, true, true);
foreach (var entry in resourceSet.OfType<DictionaryEntry>().Select((item, i) => new { Index = i, Key = item.Key, Value = item.Value }))
{
Console.WriteLine(@"[{0}] {1}", entry.Index, entry.Key);
}
W przypadku pakietu System.Resources.ResourceManager
NuGet (wersja 4.3.0) ResourceSet
i ResourceManager.GetResourceSet
nie są dostępne.
Używając ResourceReader
, jak sugeruje ten post: „ C # - Nie można pobrać ciągu z ResourceManager (z zestawu satelickiego) ”
Nadal można odczytać klucze / wartości pliku zasobów.
System.Reflection.Assembly resourceAssembly = System.Reflection.Assembly.Load(new System.Reflection.AssemblyName("YourAssemblyName"));
String[] manifests = resourceAssembly.GetManifestResourceNames();
using (ResourceReader reader = new ResourceReader(resourceAssembly.GetManifestResourceStream(manifests[0])))
{
System.Collections.IDictionaryEnumerator dict = reader.GetEnumerator();
while (dict.MoveNext())
{
String key = dict.Key as String;
String value = dict.Value as String;
}
}
Korzystanie z LINQ to SQL :
XDocument
.Load(resxFileName)
.Descendants()
.Where(_ => _.Name == "data")
.Select(_ => $"{ _.Attributes().First(a => a.Name == "name").Value} - {_.Value}");
Prosta pętla odczytu używa tego kodu
var resx = ResourcesName.ResourceManager.GetResourceSet(CultureInfo.CurrentUICulture, false, false);
foreach (DictionaryEntry dictionaryEntry in resx)
{
Console.WriteLine("Key: " + dictionaryEntry.Key);
Console.WriteLine("Val: " + dictionaryEntry.Value);
}