mercredi 26 octobre 2016

C# Generic method to get property values with Linq Expression and reflection

Dear Gods of Reflection

I would like to have a generic GetValue<TEntity, T> method that can return the following property values given the following User class:

public class User  
{
   public int Id { get; set; }
   public int ClientId { get; set; }
   public string UserName { get; set; }
   public string FirstName { get; set; }
   public string LastName { get; set; }
   public string MobileNumber { get; set; }   
   public bool IsActive { get; set; }

   public Client Client { get; set; }
   public List<Package> Packages { get; set; }

 }

Example usage of what GetValue<TEntity, T> should be able to do:

  var firstName = dataCollector.GetValue<User, string>(x => x.FirstName);
  var client = dataCollector.GetValue<User, Client>(x => x.Client);
  var packages = dataCollector.GetValue<User, List<Package>>(x => x.Packages);

  var packageFirst = dataCollector.GetValue<User, Package>(x => x.Packages[0]);
  var packageName = dataCollector.GetValue<User, string>(x => x.Packages[0].Name);
  var clientName = dataCollector.GetValue<User, string>(x => x.Client.Name);

So far I have the following method which works for the first 3 scenarios:

 public T GetValue<TEntity, T>(Expression<Func<TEntity, T>> propertyExpression) where TEntity : class
 {
    var response = _responses.FirstOrDefault(p => p.GetType() == typeof(TEntity)) as TEntity;
    if (response != null)
    {
       var expr = (MemberExpression)propertyExpression.Body;
       var prop = (PropertyInfo)expr.Member;
       return (T)prop.GetValue(response);
    }
    return default(T);
  }

But it does not work for the last 3 scenarios:

  var packageFirst = dataCollector.GetValue<User, Package>(x => x.Packages[0]);
  var packageName = dataCollector.GetValue<User, string>(x => x.Packages[0].Name);
  var clientName = dataCollector.GetValue<User, string>(x => x.Client.Name);

What changes do I need to make to the method?

I shall now sacrifice a USB flash drive whilst awaiting your answers :)





Aucun commentaire:

Enregistrer un commentaire