简体   繁体   English

在c#中获取属性的名称

[英]Getting the name of a property in c#

Given this class: 鉴于此类:

public class MyClass
{
    public int MyProperty {get; set;}
}

How will I be able to extract the name of MyProperty in code? 我如何能够在代码中提取MyProperty的名称?

For example, I am able to get the name of the class like this 例如,我可以像这样得到类的名称

typeof(MyClass).Name

How can I do something similar for the property? 我怎样才能为房产做类似的事情?

The reason for the question is that I want this particular code to be resistant against refactorizations of the names. 问题的原因是我希望这个特定的代码能够抵抗名称的重构。

EDIT: With resistant I mean that I want the code at the call site to be robust in the face of changes of the propertyname. 编辑:有耐力我的意思是我希望呼叫站点的代码在属性名称的变化面前是健壮的。 I have some stuff that is using a string representation of the property name. 我有一些使用属性名称的字符串表示的东西。 Sorry for the poor phrasing. 对不起的措辞很糟糕。 I did not include call site code in order to keep the problem clean and not wander off into other discussions on the nature of the call site code. 我没有包含呼叫站点代码以保持问题清洁,而不是徘徊在有关呼叫站点代码性质的其他讨论中。

You do it like this, using compiler generated expression trees: 你这样做,使用编译器生成的表达式树:

public static string GetMemberName<T, TValue>(Expression<Func<T, TValue>> memberAccess)
{
    return ((MemberExpression)memberAccess.Body).Member.Name;
}

Now call the static method from code: 现在从代码中调用静态方法:

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`

You can now also use refactoring to rename that field without breaking this code 您现在还可以使用重构来重命名该字段,而不会破坏此代码

In C# 6 we can do it very simply 在C#6中,我们可以非常简单地完成它

nameof(MyField);

you can get method\\type\\propery\\field\\class\\namespace names in the same way ex 您可以以相同的方式获取方法\\ type \\ propery \\ field \\ class \\ namespace名称

 nameof(MyClass);
 nameof(namespacename1)  // returns "namespacename1"
 nameof(TestEnum.FirstValue) // returns enum's first value

MSDN Reference MSDN参考

Look at this post 看看这篇文章

With C# 6.0, you can use the new nameof operator. 使用C#6.0,您可以使用新的nameof运算符。

nameof(MyClass.MyField)  // returns "MyField"
nameof(MyClass)  //returns "MyClass"

See nameof (C# and Visual Basic Reference) for more examples. 有关更多示例,请参阅nameof(C#和Visual Basic参考)

Using Reflection you can find all Members from MyClass with this. 使用Reflection您可以找到MyClass所有成员。

    MemberInfo[] members = typeof(MyClass).GetMembers();

Now you can find your desired property for each Member. 现在,您可以为每个会员找到您想要的房产。

    foreach ( MemberInfo memberInfo in members)
    {
        Console.WriteLine("Name: {0}", memberInfo.Name); // Name: MyField
        Console.WriteLine("Member Type: {0}", memberInfo.MemberType); // Member Type: Property
    }

If you want to find only Properties use PropertyInfo instead of MemberInfo . 如果只想查找属性,请使用PropertyInfo而不是MemberInfo Or write this 或写下这个

    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
    }

You could use the following class which contains a method using an expression tree as an argument to determine a member name based on a lambda expression: 您可以使用以下类,其中包含使用表达式树作为参数的方法,以根据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");
    }
}

Then use it like so: 然后像这样使用它:

MemberHelper<MyClass> memberHelper = new MemberHelper<MyClass>();
string name = memberHelper.GetName(x => x.MyField);

If you only want to get name of an instance member, you can use shorter code: 如果您只想获取实例成员的名称,则可以使用更短的代码:

    public static string GetMemberName<TValue>(Expression<Func<TValue>> memberAccess)
    {
        return ((MemberExpression)memberAccess.Body).Member.Name;
    }

And use it like the following inside the class: 并在课堂上使用它如下:

    ReflectionTools.GetMemberName(() => _someInstanceVariableOrProperty)

If you don't want to waste your time , try the following one. 如果您不想浪费时间 ,请尝试以下方法。 I know there will be people run into the same problem. 我知道会有人遇到同样的问题。

// 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}");
}

Don't forget to add using System.ComponentModel; 不要忘记using System.ComponentModel;添加using System.ComponentModel; .

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM