Answers:
您应该始终使用资源管理器,而不是直接读取文件,以确保考虑到全球化。
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"));
博客上讲述它在我的博客 :)短的版本是,寻找资源的全名(除非你已经知道它们):
var assembly = Assembly.GetExecutingAssembly();
foreach (var resourceName in assembly.GetManifestResourceNames())
System.Console.WriteLine(resourceName);
要将它们全部用于某事:
foreach (var resourceName in assembly.GetManifestResourceNames())
{
using(var stream = assembly.GetManifestResourceStream(resourceName))
{
// Do something with stream
}
}
要在执行程序集之外的其他程序集中使用资源,您可以通过使用Assembly
该类的其他一些静态方法来获得不同的程序集对象。希望能帮助到你 :)
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();
请参阅链接:Microsoft示例
System.Windows.Forms
程序集中的,如果您使用的是MVC应用,则不会自动添加
将资源.RESX文件添加到项目中的那一刻,Visual Studio将创建一个具有相同名称的Designer.cs,为您创建一个类,将资源的所有项目作为静态属性。在键入资源文件的名称后,在编辑器中键入点时,可以看到资源的所有名称。
另外,您可以使用反射来遍历这些名称。
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
}
该方法显然仅在RESX文件在当前程序集或项目的范围内时才可用。否则,请使用“脉冲”提供的方法。
此方法的优点是,您可以调用已提供给您的实际属性,并且可以根据需要考虑任何本地化。但是,这是多余的,因为通常应使用类型安全直接方法来调用资源的属性。
如果要使用LINQ,请使用resourceSet.OfType<DictionaryEntry>()
。例如,使用LINQ可让您根据索引(int)而不是键(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);
}
对于nuget软件包System.Resources.ResourceManager
(v4.3.0),ResourceSet
和ResourceManager.GetResourceSet
均不可用。
使用ResourceReader
,如本文所建议:“ C#-无法从ResourceManager(从附属程序集)获取字符串 ”
仍然可以读取资源文件的键/值。
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;
}
}
使用LINQ to SQL:
XDocument
.Load(resxFileName)
.Descendants()
.Where(_ => _.Name == "data")
.Select(_ => $"{ _.Attributes().First(a => a.Name == "name").Value} - {_.Value}");