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

I have a common problem, I'm trying to get around a certain way.

Mostly with Winforms, I am trying to set the DisplayMember and ValueMember elements in a form. You usually install it like this:

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: 2 method calls must be static in order to save the creation of objects here)

All my classes that I'm trying to do inherit from the base class "BaseObject", so I 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, to use this, I need to write the following code:

 this.testCombobox.DisplayMember = BaseObject.GetPropertyName((ClassOne c) => c.PropertyOne); 

My question is: how do I rewrite the BaseObject.GetPropertyName method to achieve what I want? I feel that I am very close, but I can’t think how to change it.

+4
source share
3 answers

Your current GetPropertyName method leaves open the general T. Therefore, the compiler cannot resolve its compilation time, since you will not specify it when using the method.

However, if you make your base class generic, and specify T in the derived class, and specify whether to use the derived class method (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); } } 
+4
source

I created a Helper class to retrieve the name Proprty

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

 PropertySupport.ExtractPropertyName(() => DateTime.Now) 

he will return "Now"

EDIT

Here is a test console application:

  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(); } } 
+4
source

I suggest the following in the general assistant:

  public static class GenericHelper<TEntity> { public static string GetPropertyName<TProperty>(Expression<Func<TEntity, TProperty>> propertyExpression) { return propertyExpression.GetPropertyName(); } } 

and the following in extensions for general use:

 public static class ReflectionExtensions { public static PropertyInfo GetProperty<TEntity, TProperty>(this Expression<Func<TEntity, TProperty>> source) { //TODO: check TEntity, if needed. Now it ignored var member = source.Body as MemberExpression; if (member == null) { throw new ArgumentException(String.Format( "Expression '{0}' refers to a method, not a property.", source)); } var propertyInfo = member.Member as PropertyInfo; if (propertyInfo == null) { throw new ArgumentException(string.Format( "Expression '{0}' refers to a field, not a property.", source)); } return propertyInfo; } public static string GetPropertyName<TEntity, TProperty>(this Expression<Func<TEntity, TProperty>> source) { return source.GetProperty().Name; } } 
0
source

Source: https://habr.com/ru/post/1492064/


All Articles