鉴于此课程:
public class MyClass
{
public int MyProperty {get; set;}
}
我如何能够在代码中提取MyProperty
的名称?
例如,我可以像这样得到类的名称
typeof(MyClass).Name
我该如何为该物业做类似的事情?
问题的原因是我希望这个特定代码能够抵制名称的重构。
编辑:我有意思是我希望呼叫站点的代码在属性名更改时是健壮的。我有一些使用属性名称的字符串表示的东西。对不起的措辞很糟糕。 我没有包含呼叫站点代码,以保持问题清洁,而不是徘徊在有关呼叫站点代码性质的其他讨论中。
答案 0 :(得分:47)
你这样做,使用编译器生成的表达式树:
public static string GetMemberName<T, TValue>(Expression<Func<T, TValue>> memberAccess)
{
return ((MemberExpression)memberAccess.Body).Member.Name;
}
现在从代码中调用静态方法:
class MyClass
{
public int Field;
public string Property { get; set; }
}
var fieldName = GetMemberName((MyClass c) => c.Field);
var propertyName = GetMemberName((MyClass c) => c.Property);
// fieldName has string value of `Field`
// propertyName has string value of `Property`
现在,您还可以使用重构来重命名该字段,而不会破坏此代码
答案 1 :(得分:27)
在C#6中,我们可以非常简单地完成
nameof(MyField);
您可以以相同的方式获取method \ type \ propery \ field \ class \ namespace名称 前
nameof(MyClass);
nameof(namespacename1) // returns "namespacename1"
nameof(TestEnum.FirstValue) // returns enum's first value
答案 2 :(得分:9)
使用C#6.0,您可以使用新的nameof
运算符。
nameof(MyClass.MyField) // returns "MyField"
nameof(MyClass) //returns "MyClass"
有关更多示例,请参阅nameof (C# and Visual Basic Reference)。
答案 3 :(得分:7)
使用反射,您可以找到MyClass
中的所有成员。
MemberInfo[] members = typeof(MyClass).GetMembers();
现在,您可以为每位会员找到所需的财产。
foreach ( MemberInfo memberInfo in members)
{
Console.WriteLine("Name: {0}", memberInfo.Name); // Name: MyField
Console.WriteLine("Member Type: {0}", memberInfo.MemberType); // Member Type: Property
}
如果您只想查找属性,请使用PropertyInfo
代替MemberInfo
。
或者写这个
foreach ( MemberInfo memberInfo in members.Where(p => p.MemberType == MemberTypes.Property))
{
Console.WriteLine("Name: {0}", memberInfo.Name); // Name: MyField
Console.WriteLine("Member Type: {0}", memberInfo.MemberType); // Member Type: Property
}
答案 4 :(得分:5)
您可以使用以下类,其中包含使用表达式树作为参数的方法,以根据lambda表达式确定成员名称:
public class MemberHelper<T>
{
public string GetName<U>(Expression<Func<T, U>> expression)
{
MemberExpression memberExpression = expression.Body as MemberExpression;
if (memberExpression != null)
return memberExpression.Member.Name;
throw new InvalidOperationException("Member expression expected");
}
}
然后像这样使用它:
MemberHelper<MyClass> memberHelper = new MemberHelper<MyClass>();
string name = memberHelper.GetName(x => x.MyField);
答案 5 :(得分:3)
如果您只想获取实例成员的名称,可以使用更短的代码:
public static string GetMemberName<TValue>(Expression<Func<TValue>> memberAccess)
{
return ((MemberExpression)memberAccess.Body).Member.Name;
}
在课堂上使用它如下:
ReflectionTools.GetMemberName(() => _someInstanceVariableOrProperty)
答案 6 :(得分:0)
如果您不想浪费时间,请尝试以下方法。我知道会有人遇到同样的问题。
// Soner - tested!
foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(item))
{
string name = descriptor.Name; // Name
object value = descriptor.GetValue(item); // Value
var type = descriptor.PropertyType; // Type
Console.WriteLine($"{name}={value}={type}");
}
别忘了添加using System.ComponentModel;
。