Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.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 - Fatal编程技术网

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。必须对其进行修改以处理该案件。或者只使用第二个重载,它没有这个问题。