Getting property names of a class using expressions, static methods, and a base object

.net, c#, c#-4.0, linq

Solution

Your current GetPropertyName method leaves open the generic T. Hence, the compiler cannot resolve it compile-time since you do not specify it when you use the method.

However, if you make your base class generic, AND specify the T in the derived class, AND specify to use the method of the derived class (and not the base class), then it works.

Like this:

public class BaseClass<T> {
    public static string GetPropertyName<P>(Expression<Func<T, P>> action) {
        MemberExpression expression = action.Body as MemberExpression;
        return expression.Member.Name;
    }
}

public class ClassOne : BaseClass<ClassOne> {
    public string PropertyOne { get; set; }
}
public static class Test {
    public static void test() {
        var displayMember = ClassOne.GetPropertyName(x => x.PropertyOne);
    }
}

Problem

I have a common problem, that I am trying to get round in a specific way. Basically with Winforms, I am trying to set the "DisplayMember" and "ValueMember" of controls in a form. You would normally set it like so: ``` this.testCombobox.DisplayMember = "PropertyOne"; this.testCombobox.ValueMember = "PropertyTwo"; ``` I want to rewrite this as follows: ``` this.testCombobox.DisplayMember = ClassOne.GetPropertyName(c => c.PropertyOne); this.testCombobox.ValueMember = ClassOne.GetPropertyName(c => c.PropertyTwo); ``` (NOTE: the 2 method calls need to be static, to save creating objects here) All of my classes that I am trying to do this, inherit from a base class "BaseObject", so I have added a method to it as follows: ``` public static string GetPropertyName<T, P>(Expression<Func<T, P>> action) where T : class { MemberExpression expression = action.Body as MemberExpression; return expression.Member.Name; } ``` However, in order to use this, I need to write the following code instead: ``` this.testCombobox.DisplayMember = BaseObject.GetPropertyName((ClassOne c) => c.PropertyOne); ``` My question is, how would I rewrite the method `BaseObject.GetPropertyName` to achieve what I want? I feel I am very close but cannot think how to change it.

Original source