C# 反射-获取属性名
我希望将属性名传递给函数,而不使用魔术字符串 比如:C# 反射-获取属性名,c#,reflection,C#,Reflection,我希望将属性名传递给函数,而不使用魔术字符串 比如: Get<ObjectType>(x=>x.Property1); Get(x=>x.Property1); 其中Property1是ObjectType类型的属性 方法实现是什么样子的?这可以通过表达式实现: // requires object instance, but you can skip specifying T static string GetPropertyName<T>(Expressio
Get<ObjectType>(x=>x.Property1);
Get(x=>x.Property1);
其中Property1是ObjectType类型的属性
方法实现是什么样子的?这可以通过表达式实现:
// requires object instance, but you can skip specifying T
static string GetPropertyName<T>(Expression<Func<T>> exp)
{
return (((MemberExpression)(exp.Body)).Member).Name;
}
// requires explicit specification of both object type and property type
static string GetPropertyName<TObject, TResult>(Expression<Func<TObject, TResult>> exp)
{
// extract property name
return (((MemberExpression)(exp.Body)).Member).Name;
}
// requires explicit specification of object type
static string GetPropertyName<TObject>(Expression<Func<TObject, object>> exp)
{
var body = exp.Body;
var convertExpression = body as UnaryExpression;
if(convertExpression != null)
{
if(convertExpression.NodeType != ExpressionType.Convert)
{
throw new ArgumentException("Invalid property expression.", "exp");
}
body = convertExpression.Operand;
}
return ((MemberExpression)body).Member.Name;
}
//需要对象实例,但可以跳过指定T
静态字符串GetPropertyName(表达式exp)
{
返回(((MemberExpression)(exp.Body)).Member.Name;
}
//需要明确指定对象类型和属性类型
静态字符串GetPropertyName(表达式exp)
{
//提取属性名
返回(((MemberExpression)(exp.Body)).Member.Name;
}
//需要对象类型的显式规范
静态字符串GetPropertyName(表达式exp)
{
变量体=实验体;
var convertExpression=主体作为一元表达式;
if(convertExpression!=null)
{
if(convertExpression.NodeType!=ExpressionType.Convert)
{
抛出新ArgumentException(“无效的属性表达式。”,“exp”);
}
body=convertExpression.Operand;
}
返回((MemberExpression)body).Member.Name;
}
用法:
var x = new ObjectType();
// note that in this case we don't need to specify types of x and Property1
var propName1 = GetPropertyName(() => x.Property1);
// assumes Property2 is an int property
var propName2 = GetPropertyName<ObjectType, int>(y => y.Property2);
// requires only object type
var propName3 = GetPropertyName<ObjectType>(y => y.Property3);
var x=new ObjectType();
//注意,在这种情况下,我们不需要指定x和Property1的类型
var propName1=GetPropertyName(()=>x.Property1);
//假设Property2是int属性
var propName2=GetPropertyName(y=>y.Property2);
//只需要对象类型
var propName3=GetPropertyName(y=>y.Property3);
更新:修复了返回值类型的属性的GetPropertyName(Expression)
。class Foo
class Foo
{
public string Bar { get; set; }
}
class Program
{
static void Main()
{
var result = Get<Foo, string>(x => x.Bar);
Console.WriteLine(result);
}
static string Get<T, TResult>(Expression<Func<T, TResult>> expression)
{
var me = expression.Body as MemberExpression;
if (me != null)
{
return me.Member.Name;
}
return null;
}
}
{
公共字符串条{get;set;}
}
班级计划
{
静态void Main()
{
var result=Get(x=>x.Bar);
控制台写入线(结果);
}
静态字符串Get(表达式)
{
var me=expression.Body作为MemberExpression;
如果(me!=null)
{
返回me.Member.Name;
}
返回null;
}
}
是否有机会在不首先创建实例和不使用空括号的情况下使其工作?只是(x=>x.Prop1)为这种情况添加了一个重载(虽然代码是相同的,Darin的答案中已经表达了想法)。有一个小问题,我必须指定可以处理的属性类型(int,string…)?添加了第三个重载来处理这个问题。第三个重载崩溃,因为有时候exp.Body的类型是UnaryExpression。必须对其进行修改以处理该案件。或者只使用第二个重载,它没有这个问题。