简体   繁体   中英

Is it possible to get an object property name string without creating the object instance?

A string representation of an object instance property can be taken with Expression<Func<T>> :

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

But what if I don't have (don't want to create) the instance? How do I get the property name in this case?

Explained

I need a string representation of a property name of some object.

Let's say there is an entity

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

Now I want to pass the key expression of this entity to some other function, thus I need the string "ID", but I don't want to hardcode the string like SomeOtherFunction("ID") , instead I use the expression SomeOtherFunction(ExpressionReader.GetString(() => CustomerInstance.ID)) . For this to work I need to supply the entity instance.

Now I want to do the same without creating the instance.

This is possible with a method signature like the following:

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

    return memberExpression.Member.Name;
}

You can call this method without an instance of the customer class:

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

Of course you should add some checks for correct expression types before you cast to MemberExpression and access memberExpression.Member.Name .

No, you dont need an instance to decompose the Expression . Even if the expression expects one, you will never invoke it.

In fact, you do it just like you did in first code snippet.

You would change you code to look like this then:

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

Does that make sense to you?

Alternatively:

Customer c = null; // null intentionally

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

Still no problem as you are not invoking the expression.

With the new nameof operator of C# 6 I would suggest the following:

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

The selected answer is good but does not cover UnaryExpressions. It will fail when trying to get the property of a 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;
        }  
    }

I'm not sure I fully understand what you mean, but based on my understanding you could use Reflection. Using this approach, if you had the Type of what you wanted to get a property name from, then you could retrieve the properties using:

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

Once you have instance(s) of the PropertyInfo class, you can retrieve information such as the property name.

For more information on this approach, see the MSDN Documentation .

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