【问题标题】:Reflection - get property name [duplicate]反射 - 获取属性名称
【发布时间】:2011-01-11 11:52:46
【问题描述】:

我想在不使用魔术字符串的情况下将属性名称传递给函数。

类似:

Get<ObjectType>(x=>x.Property1);

其中 Property1 是 ObjectType 类型的属性。

方法实现是什么样的?

【问题讨论】:

    标签: c# reflection


    【解决方案1】:

    这可以使用表达式来实现:

    // 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;
    }
    

    用法:

    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);
    

    更新:为返回值类型的属性修复了 GetPropertyName&lt;TObject&gt;(Expression&lt;Func&lt;TObject, object&gt;&gt; exp)

    【讨论】:

    • 是否有机会在不先创建实例且没有空括号的情况下使其工作?只是 (x=>x.Prop1)
    • 为这种情况添加了一个重载(代码是相同的,并且想法已经在达林的回答中表达了)。
    • 有个小问题,我要指定属性类型(int,string..) 可以这样处理吗?
    • 添加了处理这个问题的第三个过载
    • 第三个重载崩溃,因为有时 exp.Body 是 UnaryExpression 类型。必须对其进行修改以处理这种情况。或者只使用不存在此问题的第二个重载。
    【解决方案2】:
    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;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-02
      • 1970-01-01
      • 2013-04-24
      • 2012-09-01
      • 2010-11-15
      • 2012-05-23
      • 1970-01-01
      • 2012-02-05
      相关资源
      最近更新 更多