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.
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);
}
}
I created a Helper class to extract Proprty Name
public static class PropertySupport
{
public static string ExtractPropertyName<T>(Expression<Func<T>> propertyExpression)
{
if (propertyExpression == null)
{
throw new ArgumentNullException("propertyExpression");
}
var memberExpression = propertyExpression.Body as MemberExpression;
if (memberExpression == null)
{
throw new ArgumentException("Invalide Expression", "propertyExpression");
}
return memberExpression.Member.Name;
}
}
And you can use it as Follows :
PropertySupport.ExtractPropertyName(() => DateTime.Now)
it will return "Now"
EDIT
Here is a test console app:
public static class PropertySupport
{
public static string ExtractPropertyName<T>(Expression<Func<T>> propertyExpression)
{
if (propertyExpression == null)
{
throw new ArgumentNullException("propertyExpression");
}
var memberExpression = propertyExpression.Body as MemberExpression;
if (memberExpression == null)
{
throw new ArgumentException("", "propertyExpression");
}
return memberExpression.Member.Name;
}
}
public class MyClass
{
public MyClass PropertyOne { get; set; }
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine(PropertySupport.ExtractPropertyName(() => new MyClass().PropertyOne));
Console.ReadKey();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With