Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用反射获取C#静态类属性的名称?_C#_Reflection_Static_Properties - Fatal编程技术网

如何使用反射获取C#静态类属性的名称?

如何使用反射获取C#静态类属性的名称?,c#,reflection,static,properties,C#,Reflection,Static,Properties,我想制作一个C#字典,其中键是类中静态属性的字符串名称,值是属性的值。如果类中有一个名为MyResources.TOKEN_ONE的静态属性,如何获取该属性的名称而不是其值?我只关心属性名称的结尾部分(例如“TOKEN_ONE”) 我编辑了这篇文章是为了说明我不想映射字典中的所有属性值,只映射类中所有属性值的一小部分。因此,假设我想要获取单个属性的名称。给定MyResources.TOKEN\u ONE,我想返回“MyResources.TOKEN\u ONE”或只是“TOKEN\u ONE”

我想制作一个C#字典,其中键是类中静态属性的字符串名称,值是属性的值。如果类中有一个名为MyResources.TOKEN_ONE的静态属性,如何获取该属性的名称而不是其值?我只关心属性名称的结尾部分(例如“TOKEN_ONE”)

我编辑了这篇文章是为了说明我不想映射字典中的所有属性值,只映射类中所有属性值的一小部分。因此,假设我想要获取单个属性的名称。给定MyResources.TOKEN\u ONE,我想返回“MyResources.TOKEN\u ONE”或只是“TOKEN\u ONE”

下面是一些示例代码,展示了我正在尝试做的事情。我需要属性名,因为我试图生成一个javascript变量,在该变量中,我将属性名映射到变量名,将属性值映射到变量值。例如,我希望C#字典生成如下所示的行:

var TOKEN_ONE=“ONE”

使用系统;
使用System.Collections.Generic;
名称空间MyConsoleApp
{
班级计划
{
静态void Main(字符串[]参数)
{
Dictionary kvp=新字典();
//如何使用类中静态属性的名称作为字典的键?
//例如,我想执行以下操作,其中“PropertyNameFromReflection”
//是一种返回“MyResources.TOKEN_ONE”的机制
添加(MyResources.TOKEN\u ONE.PropertyNameFromReflection,MyResources.TOKEN\u ONE);
添加(MyResources.TOKEN\u TWO.PropertyNameFromReflection,MyResources.TOKEN\u TWO);
Console.ReadLine();
}
}
公共静态类MyResources
{
公共静态字符串令牌\u ONE
{
获取{返回“一”;}
}
公共静态字符串标记\u 2
{
获取{return“Two”;}
}
}
}

您可以通过反射来实现这一点。获取属性名的最简单方法是循环所有属性名


有关更多详细信息,请参阅和。

这里有一个函数,它将为您提供给定类型中所有静态属性的名称

public static IEnumerable<string> GetStaticPropertyNames(Type t) {
  foreach ( var prop in t.GetProperties(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) ) {
    yield return prop.Name; 
  }
}

嗯,我不情愿地回答我自己的问题,因为我认为不可能对单个静态属性这样做。最终,我使用属性名的剪切粘贴在字典中硬编码了键。以下是我最终得到的结果:

  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);
  }
protecteddictionary\u javaScriptTokens=newdictionary();
public void AddJavaScriptToken(字符串tokenValue、字符串propertyName)
{
_Add(propertyName,tokenValue);
}
受保护的覆盖无效OnPreRender(EventArgs e)
{
如果(_javaScriptTokens.Count>0)
{
StringBuilder sb=新的StringBuilder();
foreach(javaScriptTokens中的KeyValuePair kvp)
{
sb.AppendLine(String.Format(“var-TOKEN{0}=unescape('{1}');”,kvp.Key,PUtilities.Escape(kvp.Value));
}
RegisterStartupScript(this.GetType(),“PAGE_TOKENS”,sb.ToString(),true);
}
基于预渲染(e);
}

我讨厌使用剪切粘贴硬编码来保持属性名称和键同步…哦,好吧…

其他答案已经解释了如何通过反射获得静态属性列表。你说你不想要所有的,只想要其中的一个子集。因此,您似乎需要一种方法来区分想要的属性和不想要的属性。一种方法是使用自定义属性

声明自定义属性类:

[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;
}
将此自定义属性添加到所需的属性中:

[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;
}
迭代属性以找到所需的属性:

[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;
}
公共静态字典GetStaticPropertyBag(类型t)
{
var flags=BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
var map=newdictionary();
foreach(t.GetProperties中的var prop(标志))
if(prop.IsDefined(typeof(WantThisAttribute),true))
map[prop.Name]=prop.GetValue(null,null);
返回图;
}

如果您只想在代码中的一个位置引用一个特定的属性,而不必通过文本字符串引用它,那么您可以使用表达式树。例如,以下代码声明了一个方法,该方法将此类表达式树转换为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;
}
publicstaticpropertyinfo GetProperty(Expression-expr)
{
var member=expr.Body作为MemberExpression;
if(成员==null)
抛出新的InvalidOperationException(“表达式不是成员访问表达式”);
var property=member.member作为PropertyInfo;
if(属性==null)
抛出新的InvalidOperationException(“表达式中的成员不是属性”);
归还财产;
}
现在您可以执行以下操作:

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);
}
public void AddJavaScriptToken(表达式属性Expression)
{
var p=GetProperty(propertyExpression);
_Add(p.Name,(string)p.GetValue(null,null));
}
公共无效注册表JavaScriptTokens()
{
AddJavaScriptToken(()=>Tokens.TOKEN_ONE);
AddJavaScriptToken(()=>Tokens.TOKEN_TWO);
}

不,这不适合我。我已将您的代码片段添加到我的控制台测试应用程序中,但foreach循环仅为.Name属性返回“Chars”和“Length”。我需要返回'MyResources.TOKEN_ONE'我使用了以下语法:foreach(MyResources.TOKEN_ONE.GetType().GetProperties())中的var-propInfo…我应该在OP中指定我不想枚举给定类中的所有静态属性,只是我感兴趣的一个很小的子集。我将在下面的一篇较长的帖子中对此进行澄清。现实世界的情况是,我有一个自动生成的C#WebResources类,它由每个RESX strin组成