我想创建一个C#Dictionary,其中key是类中静态属性的字符串名称,value是属性的值。给定名为MyResources.TOKEN_ONE的类中的静态属性,如何获取属性的名称而不是其值?我只关心属性名称的末尾部分(例如“TOKEN_ONE”)。
我编辑过这个,提到我不想在词典中映射所有属性值,只是该类中所有内容的一小部分。所以假设我想获得单个属性的名称。给定MyResources.TOKEN_ONE,我想取回“MyResources.TOKEN_ONE”或“TOKEN_ONE”。
这是一些示例代码,显示了我正在尝试做的事情。我需要属性名称,因为我正在尝试生成一个javascript变量,其中我将属性名称映射到变量名称,将属性值映射到变量值。例如,我希望C#Dictionary生成如下所示的行:
var TOKEN_ONE =“一个”;
using System;
using System.Collections.Generic;
namespace MyConsoleApp
{
class Program
{
static void Main(string[] args)
{
Dictionary<String, String> kvp = new Dictionary<String, String>();
// How can I use the name of static property in a class as the key for the dictionary?
// For example, I'd like to do something like the following where 'PropertyNameFromReflection'
// is a mechanism that would return "MyResources.TOKEN_ONE"
kvp.Add(MyResources.TOKEN_ONE.PropertyNameFromReflection, MyResources.TOKEN_ONE);
kvp.Add(MyResources.TOKEN_TWO.PropertyNameFromReflection, MyResources.TOKEN_TWO);
Console.ReadLine();
}
}
public static class MyResources
{
public static string TOKEN_ONE
{
get { return "One"; }
}
public static string TOKEN_TWO
{
get { return "Two"; }
}
}
}
答案 0 :(得分:4)
如果您只想在代码中的某个位置引用单个特定属性,而不必通过文字字符串引用它,那么您可以使用表达式树。例如,以下代码声明了一个将这种表达式树转换为PropertyInfo对象的方法:
public static PropertyInfo GetProperty(Expression<Func<string>> expr)
{
var member = expr.Body as MemberExpression;
if (member == null)
throw new InvalidOperationException("Expression is not a member access expression.");
var property = member.Member as PropertyInfo;
if (property == null)
throw new InvalidOperationException("Member in expression is not a property.");
return property;
}
现在你可以这样做:
public void AddJavaScriptToken(Expression<Func<string>> propertyExpression)
{
var p = GetProperty(propertyExpression);
_javaScriptTokens.Add(p.Name, (string) p.GetValue(null, null));
}
public void RegisterJavaScriptTokens()
{
AddJavaScriptToken(() => Tokens.TOKEN_ONE);
AddJavaScriptToken(() => Tokens.TOKEN_TWO);
}
答案 1 :(得分:2)
这是一个函数,它将为您提供给定类型中所有静态属性的名称。
public static IEnumerable<string> GetStaticPropertyNames(Type t) {
foreach ( var prop in t.GetProperties(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) ) {
yield return prop.Name;
}
}
如果要将所有属性名称的地图构建为其值,可以执行以下操作
public static Dictionary<string,object> GetStaticPropertyBag(Type t) {
var flags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
var map = new Dictionary<string,object>();
foreach ( var prop in t.GetProperties(flags) ) {
map[prop.Name] = prop.GetValue(null,null);
}
return map;
}
现在您可以使用以下
来调用它var bag = GetStaticPropertyBag(typeof(MyResources));
答案 2 :(得分:0)
你可以用反射完成这个。获取属性名称的最简单方法是遍历所有。
foreach(var propInfo in this.GetType().GetProperties()) {
var name = propInfo.Name;
var value = propInfo.GetValue(this, null);
}
有关详细信息,请参阅GetProperties()和GetValue()。
答案 3 :(得分:0)
好吧,我不情愿地回答我自己的问题,因为我觉得不可能为一个静态属性做这件事。最后,我最终使用属性名称的剪切和粘贴对字典中的键进行了硬编码。这就是我最终的结果:
public void RegisterJavaScriptTokens()
{
AddJavaScriptToken(Token.FOOBAR_TITLE, "FOOBAR_TITLE");
}
以下是代码的其余部分:
protected Dictionary<String, String> _javaScriptTokens = new Dictionary<String, String>();
public void AddJavaScriptToken(string tokenValue, string propertyName)
{
_javaScriptTokens.Add(propertyName, tokenValue);
}
protected override void OnPreRender(EventArgs e)
{
if (_javaScriptTokens.Count > 0)
{
StringBuilder sb = new StringBuilder();
foreach (KeyValuePair<String, String> kvp in _javaScriptTokens)
{
sb.AppendLine(String.Format("var TOKEN_{0} = unescape('{1}');", kvp.Key, PUtilities.Escape(kvp.Value)));
}
ClientScript.RegisterStartupScript(this.GetType(), "PAGE_TOKENS", sb.ToString(), true);
}
base.OnPreRender(e);
}
我讨厌使用剪切和粘贴硬编码来保持属性名称和密钥同步......好吧......
答案 4 :(得分:0)
其他答案已经解释了如何通过Reflection获取静态属性列表。你说你不想要所有,只是它们的一部分。因此,您似乎需要一种方法来区分您想要的属性和您不想要的属性。一种方法是使用自定义属性。
声明自定义属性类:
[AttributeUsage(AttributeTargets.Property)]
public class WantThisAttribute : Attribute { }
将此自定义属性添加到所需的属性:
public static class MyResources
{
[WantThis]
public static string TOKEN_ONE { get { return "One"; } }
[WantThis]
public static string TOKEN_TWO { get { return "Two"; } }
public static string DontWantThis { get { return "Nope"; } }
}
遍历属性以找到您想要的属性:
public static Dictionary<string, object> GetStaticPropertyBag(Type t)
{
var flags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
var map = new Dictionary<string, object>();
foreach (var prop in t.GetProperties(flags))
if (prop.IsDefined(typeof(WantThisAttribute), true))
map[prop.Name] = prop.GetValue(null,null);
return map;
}