首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用Linq表达式和反射获取属性值的泛型方法

用Linq表达式和反射获取属性值的泛型方法
EN

Stack Overflow用户
提问于 2016-10-26 13:23:07
回答 2查看 2.9K关注 0票数 2

亲爱的反思之神

我希望有一个泛型的GetValue<TEntity, T>方法,它可以返回以下属性值,给定以下User类:

代码语言:javascript
复制
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; }

 }

GetValue<TEntity, T>应该能够做的事情的示例用法:

代码语言:javascript
复制
  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);

到目前为止,我有以下方法,适用于前3种场景:

代码语言:javascript
复制
 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);
  }

但在最后3种情况下,它不起作用:

代码语言:javascript
复制
  var packageFirst = dataCollector.GetValue<User, Package>(x => x.Packages[0]);

投球:Unable to cast object of type 'System.Linq.Expressions.InstanceMethodCallExpressionN' to type 'System.Linq.Expressions.MemberExpression'.

代码语言:javascript
复制
  var packageName = dataCollector.GetValue<User, string>(x => x.Packages[0].Name);

投球:Object does not match target type.

代码语言:javascript
复制
  var clientName = dataCollector.GetValue<User, string>(x => x.Client.Name);

投球:Object does not match target type.

我需要对这个方法做什么改变?

我现在将牺牲一个USB闪存盘,同时等待您的回答:)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-10-26 14:02:35

问题在于:

代码语言:javascript
复制
if (response != null)
{
   var expr = (MemberExpression)propertyExpression.Body;
   var prop = (PropertyInfo)expr.Member;
   return (T)prop.GetValue(response);
}

这只有在表达式直接引用属性时才有效,否则propertyExpression.Body将不是MemberExpression,您将得到一个运行时强制转换错误。不起作用的三种方法不直接引用属性--前两种尊敬是属性顶部的方法(索引器),最后一种是嵌套属性。

但是,由于您只需要表达式的值,所以我认为您可以这样做:

代码语言:javascript
复制
if (response != null)
{
   Func<TEntity, T> func = propertyExpression.Compile();  
   return func(response);
}

如果您打算对表达式执行其他操作(比如获取属性的名称),那么您需要决定是否支持不直接引用属性的表达式,并为此添加处理程序。

票数 4
EN

Stack Overflow用户

发布于 2016-10-26 14:25:41

只需执行Lambda表达式即可:

代码语言:javascript
复制
        if (response != null)
        {
            return propertyExpression.Compile().Invoke(response);
        }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40263509

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档