[英]How can I Get the property by name from type and Set Propert value using reflection in C#
[英]How can I get the name of a C# static class property using reflection?
我想制作一個C#詞典,其中的鍵是類中靜態屬性的字符串名稱,而值是該屬性的值。 給定名為MyResources.TOKEN_ONE的類中的靜態屬性,如何獲取屬性名稱而不是其值? 我只關心屬性名稱的結尾部分(例如“ TOKEN_ONE”)。
我進行了編輯,以提及我不想映射Dictionary中的所有屬性值,而只是映射類中所有內容的一小部分。 因此,假設我要獲取單個屬性的名稱。 給定MyResources.TOKEN_ONE,我想找回“ MyResources.TOKEN_ONE”或“ TOKEN_ONE”。
這是一些示例代碼,顯示了我要執行的操作。 我需要屬性名稱,因為我試圖生成一個JavaScript變量,在其中將屬性名稱映射到變量名稱,並將屬性值映射到變量值。 例如,我希望C#詞典生成類似於以下內容的行:
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"; }
}
}
}
如果只需要能夠在代碼中的一個位置引用單個特定屬性, 而不必通過文字字符串來引用它,則可以使用表達式樹。 例如,以下代碼聲明了一個將這樣的表達式樹轉換為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);
}
這是一個函數,它將為您提供給定類型的所有靜態屬性的名稱。
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));
您可以通過反射來實現。 獲取屬性名稱的最簡單方法是遍歷所有屬性。
foreach(var propInfo in this.GetType().GetProperties()) {
var name = propInfo.Name;
var value = propInfo.GetValue(this, null);
}
有關更多詳細信息,請參見GetProperties()和GetValue() 。
好吧,我無奈地回答了我自己的問題,因為我認為不可能對單個靜態屬性執行此操作。 最終,我最終使用屬性名稱的剪切粘貼功能在“字典”中對密鑰進行了硬編碼。 我最終得到的是:
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);
}
我討厭不得不使用剪切和粘貼硬編碼來使屬性名稱和密鑰保持同步...哦...
其他答案已經解釋了如何通過反射獲得靜態屬性列表。 您說過,您不想要所有這些,而只是其中的一部分。 因此,似乎需要一種方法來區分所需的屬性和不需要的屬性。 一種方法是使用自定義屬性。
聲明一個自定義屬性類:
[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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.