【问题标题】:Get property name and type using lambda expression使用 lambda 表达式获取属性名称和类型
【发布时间】:2010-09-21 09:31:47
【问题描述】:

我正在尝试编写一个函数,该函数将使用如下语法提取属性名称和类型:

private class SomeClass
{
    Public string Col1;
}

PropertyMapper<Somewhere> propertyMapper = new PropertyMapper<Somewhere>();
propertyMapper.MapProperty(x => x.Col1)

有没有什么方法可以将属性传递给函数而不需要对这个语法进行任何重大更改?

我想获取属性名称和属性类型。

所以在下面的例子中我想检索

Name = "Col1" 和 Type = "System.String"

谁能帮忙?

【问题讨论】:

  • 更大的图景是什么?为什么不直接将“Col1”作为字符串名称传递并使用反射来查找该成员?是什么激发了 lambda?
  • 我正在为我的工作开发一个内部 ORM。我想轻松支持更改属性名称,而不必到处搜索字符串,而且它(在我看来)提供了一个干净的语法

标签: c# reflection lambda


【解决方案1】:

这里有足够的示例使用Expressions 获取属性或字段的名称以帮助您入门:

public static MemberInfo GetMemberInfo<T, U>(Expression<Func<T, U>> expression)
{
    var member = expression.Body as MemberExpression;
    if (member != null)
        return member.Member;

    throw new ArgumentException("Expression is not a member access", "expression");
}

调用代码如下所示:

public class Program
{
    public string Name
    {
        get { return "My Program"; }
    }

    static void Main()
    {
        MemberInfo member = ReflectionUtility.GetMemberInfo((Program p) => p.Name);
        Console.WriteLine(member.Name);
    }
}

但请注意:(Program p) =&gt; p.Name 的简单声明实际上涉及大量工作(并且可能需要大量时间)。考虑缓存结果而不是频繁调用方法。

【讨论】:

  • 永远记住,lambda 表达式可以转换为委托或表达式树。
  • 警告:GetMemberInfo 实现不是很安全 - stackoverflow.com/questions/6658669/…。也就是说,您可以使用它来读取名称。但返回的会员信息本身并不准确。
【解决方案2】:

这可以在 C# 6 中轻松完成。要获取属性名称,请使用 nameof 运算符。

nameof(User.UserId)

要获取属性类型,请使用 typeof 运算符。

typeof(User.UserId)

【讨论】:

    【解决方案3】:

    我发现这非常有用。

    public class PropertyMapper<T>
    {
        public virtual PropertyInfo PropertyInfo<U>(Expression<Func<T, U>> expression)
        {
            var member = expression.Body as MemberExpression;
            if (member != null && member.Member is PropertyInfo)
                return member.Member as PropertyInfo;
    
            throw new ArgumentException("Expression is not a Property", "expression");
        }
    
        public virtual string PropertyName<U>(Expression<Func<T, U>> expression)
        {
            return PropertyInfo<U>(expression).Name;
        }
    
        public virtual Type PropertyType<U>(Expression<Func<T, U>> expression)
        {
            return PropertyInfo<U>(expression).PropertyType;
        }
    }
    

    我按照最初的要求做了这个小班。 如果您需要属性的名称,可以这样使用:

    PropertyMapper<SomeClass> propertyMapper = new PropertyMapper<SomeClass>();
    string name = propertyMapper.PropertyName(x => x.Col1);
    

    【讨论】:

      【解决方案4】:

      我只是想我会把它放在这里以建立以前的方法。

      public static class Helpers
      {
          public static string PropertyName<T>(Expression<Func<T>> expression)
          {
              var member = expression.Body as MemberExpression;
              if (member != null && member.Member is PropertyInfo)
                  return member.Member.Name;
      
              throw new ArgumentException("Expression is not a Property", "expression");
          }
      }
      

      然后您可以按以下方式调用它:

      Helpers.PropertyName(() => TestModel.TestProperty);
      

      我还应该指出,在 VS 2015 和 C# 6.0 中,您可以简单地使用 nameof。

      https://msdn.microsoft.com/en-us/library/dn986596.aspx

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-04-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多