对象实例属性的字符串表示可以与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))
。为此,我需要提供实体实例。
现在我想做同样的而不用创建实例。
答案 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;
}
}