是否可以在不创建对象实例的情况下获取对象属性名称字符串?

时间:2011-11-15 12:41:01

标签: c# lambda properties

对象实例属性的字符串表示可以与Expression<Func<T>>一起使用:

string propertyName = ((MemberExpression) property.Body).Member.Name;

但是如果我没有(不想创建)实例呢?在这种情况下如何获取属性名称?

解释

我需要一个对象的属性名称的字符串表示。

假设有一个实体

public class Customer
{
    public int ID;
    public string Name;
}

现在我想将此实体的键表达式传递给其他函数,因此我需要字符串“ID”,但我不想像SomeOtherFunction("ID")那样对字符串进行硬编码,而是使用表达式SomeOtherFunction(ExpressionReader.GetString(() => CustomerInstance.ID))。为此,我需要提供实体实例。

现在我想做同样的而不用创建实例。

5 个答案:

答案 0 :(得分:15)

使用如下方法签名可以实现:

private static string GetPropertyName<TModel, TProperty>(Expression<Func<TModel, TProperty>> property)
{
    MemberExpression memberExpression = (MemberExpression)property.Body;

    return memberExpression.Member.Name;
}

您可以在没有客户类实例的情况下调用此方法:

string propertyName = GetPropertyName((Customer c) => c.ID);

当然,在转换为MemberExpression并访问memberExpression.Member.Name之前,您应该为正确的表达式类型添加一些检查。

答案 1 :(得分:4)

不,你不需要一个实例来分解Expression。即使表达式需要一个,你也永远不会调用它。

事实上,你就像在第一段代码片段中那样做。

您可以将代码更改为:

SomeOtherFunction(ExpressionReader<Customer>.GetString(c => c.ID))

这对你有意义吗?

可替换地:

Customer c = null; // null intentionally

SomeOtherFunction(ExpressionReader.GetString(() => c.ID));

因为你没有调用表达式,所以仍然没有问题。

答案 2 :(得分:2)

使用C#6的新名称运算符,我建议如下:

 private string GetNameMyProperty1(TestC c = null)
 {
     return nameof(c.MyProperty1);
 }

答案 3 :(得分:0)

我不确定我完全理解你的意思,但根据我的理解,你可以使用反射。使用这种方法,如果您有Type想要获取属性名称的内容,那么您可以使用以下方法检索属性:

Type someType = typeof(SomeClass);

// Get all properties for a type
PropertyInfo[] properties = someType.GetProperties();

// Get a property from a type by it's name
PropertyInfo property = someType.GetProperty("PropertyName");

获得PropertyInfo类的实例后,您可以检索属性名称等信息。

有关此方法的详细信息,请参阅MSDN Documentation

答案 4 :(得分:0)

选择的答案很好,但不包括UnaryExpressions。尝试获取DateTime的属性时会失败:

    private static string GetPropertyName<TModel, TProperty>(Expression<Func<TModel, TProperty>> property)
    {
        if (property.Body is MemberExpression)
        {
            return ((MemberExpression)property.Body).Member.Name;
        }
        else
        {
            var op = ((UnaryExpression)property.Body).Operand;
            return ((MemberExpression)op).Member.Name;
        }  
    }