简体   繁体   中英

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?

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

nameof(MyField);

you can get method\\type\\propery\\field\\class\\namespace names in the same way ex

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

MSDN Reference

Look at this post

With C# 6.0, you can use the new nameof operator.

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

See nameof (C# and Visual Basic Reference) for more examples.

Using Reflection you can find all Members from MyClass with this.

    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 . 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:

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; .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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