使用 lambda 表达式获取属性名称和类型

Posted

技术标签:

【中文标题】使用 lambda 表达式获取属性名称和类型【英文标题】:Get property name and type using lambda expression 【发布时间】: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。我想轻松支持更改属性名称,而不必到处搜索字符串,而且它(在我看来)提供了一个干净的语法 【参考方案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 实现不是很安全 - ***.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

【讨论】:

以上是关于使用 lambda 表达式获取属性名称和类型的主要内容,如果未能解决你的问题,请参考以下文章

从 lambda 表达式中获取属性名称*没有*对象实例

用于从实体类及其导航属性中选择多个列的 Linq Lambda 表达式

csharp C#使用Lambda表达式为动态类型和动态属性排序通用列表

定义通用的可通过lambda表达式树来获取属性信息

C# 无法从 lambda 表达式中获取类属性值

如何使用 lambda 表达式来获取属性“路径”和值?