Pet*_*ras 34 c# reflection variables
可能重复:
查找传递给C#中函数的变量名称
下面的课程包含现场城市.
我需要动态确定字段名称,因为它是在类声明中输入的,即我需要从对象城市的实例中获取字符串"city".
我试图通过检查其在DoSomething()中的类型来做到这一点,但在检查调试器中的Type的内容时找不到它.
可能吗?
public class Person
{
public string city = "New York";
public Person()
{
}
public void DoSomething()
{
Type t = city.GetType();
string field_name = t.SomeUnkownFunction();
//would return the string "city" if it existed!
}
}
Run Code Online (Sandbox Code Playgroud)
下面他们的答案中的一些人问我为什么要这样做.这就是原因.
在我的真实世界中,城市上方有一个自定义属性.
[MyCustomAttribute("param1", "param2", etc)]
public string city = "New York";
Run Code Online (Sandbox Code Playgroud)
我需要在其他代码中使用此属性.要获取属性,我使用反射.在反射代码中我需要输入字符串"city"
MyCustomAttribute attr;
Type t = typeof(Person);
foreach (FieldInfo field in t.GetFields())
{
if (field.Name == "city")
{
//do stuff when we find the field that has the attribute we need
}
}
Run Code Online (Sandbox Code Playgroud)
现在这不是类型安全的.如果我在Person中的字段声明中将变量"city"更改为"workCity",则此行将失败,除非我知道更新字符串
if (field.Name == "workCity")
//I have to make this change in another file for this to still work, yuk!
{
}
Run Code Online (Sandbox Code Playgroud)
因此,我试图找到一些方法将字符串传递给此代码,而无需实际键入它.
是的,我可以将它声明为Person中的字符串常量(或类似的东西),但仍然会输入两次.
唷!这很难解释!
谢谢
感谢所有回答*的人*.它让我走上了一条新的道路来更好地理解lambda表达式.它创造了一个新问题.
小智 50
也许你需要这个.工作良好.
我在这里找到了这个.
static void Main(string[] args)
{
var domain = "matrix";
Check(() => domain);
Console.ReadLine();
}
static void Check<T>(Expression<Func<T>> expr)
{
var body = ((MemberExpression)expr.Body);
Console.WriteLine("Name is: {0}", body.Member.Name);
Console.WriteLine("Value is: {0}", ((FieldInfo)body.Member)
.GetValue(((ConstantExpression)body.Expression).Value));
}
Run Code Online (Sandbox Code Playgroud)
输出将是:
Name is: 'domain' Value is: 'matrix'
Mar*_*kos 37
我知道这是一个老问题,但我试图达到同样的目的,谷歌把我送到了这里.几个小时后,我终于找到了办法.我希望其他人会觉得这很有用.
实际上有更多方法可以实现这一目标:
static void Main(string[] args)
{
GetName(new { var1 });
GetName2(() => var1);
GetName3(() => var1);
}
static string GetName<T>(T item) where T : class
{
return typeof(T).GetProperties()[0].Name;
}
static string GetName2<T>(Expression<Func<T>> expr)
{
return ((MemberExpression)expr.Body).Member.Name;
}
static string GetName3<T>(Func<T> expr)
{
return expr.Target.GetType().Module.ResolveField(BitConverter.ToInt32(expr.Method.GetMethodBody().GetILAsByteArray(), 2)).Name;
}
Run Code Online (Sandbox Code Playgroud)
第一个是最快的.最后2个比第1个慢约20倍.
http://abdullin.com/journal/2008/12/13/how-to-find-out-variable-or-parameter-name-in-c.html
city在这种情况下是类型的实例string.当您致电时,.GetType()您将返回实际的字符串类型,该类型对您的所有特定城市实例都不了解.
我很难理解为什么你不能在代码中输入"city"作为字符串文字,如果那就是你需要的.如果您分享了您想要使用此值的内容以及在何种情况下您将调用您的DoSomething()函数,这可能会有所帮助.
目前,我最好的猜测是你真正想要做的是反映整个Person班级以获得该班级中的字段列表:
public void DoSomething()
{
MemberInfo[] members = this.GetType().GetMembers();
// now you can do whatever you want with each of the members,
// including checking their .Name properties.
}
Run Code Online (Sandbox Code Playgroud)
好的,根据你的编辑我还有更多的东西给你.
您可以在运行时找到使用属性修饰的字段名称,如下所示:
Type t = typeof(Person);
foreach (MemberInfo member in t.GetMembers()
.Where(m =>
m.GetCustomAttributes(typeof(MyCustomAttribute)).Any() ) )
{
// "member" is a MemberInfo object for a Peson member that is
// decorated with your attribute
}
Run Code Online (Sandbox Code Playgroud)
如果需要,您还可以在第一个GetMembers()调用中使用绑定标志将其限制为仅字段.