亲爱的反思之神
我希望有一个泛型的GetValue<TEntity, T>方法,它可以返回以下属性值,给定以下User类:
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>应该能够做的事情的示例用法:
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种场景:
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种情况下,它不起作用:
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'.
var packageName = dataCollector.GetValue<User, string>(x => x.Packages[0].Name);投球:Object does not match target type.
var clientName = dataCollector.GetValue<User, string>(x => x.Client.Name);投球:Object does not match target type.
我需要对这个方法做什么改变?
我现在将牺牲一个USB闪存盘,同时等待您的回答:)
发布于 2016-10-26 14:02:35
问题在于:
if (response != null)
{
var expr = (MemberExpression)propertyExpression.Body;
var prop = (PropertyInfo)expr.Member;
return (T)prop.GetValue(response);
}这只有在表达式直接引用属性时才有效,否则propertyExpression.Body将不是MemberExpression,您将得到一个运行时强制转换错误。不起作用的三种方法不直接引用属性--前两种尊敬是属性顶部的方法(索引器),最后一种是嵌套属性。
但是,由于您只需要表达式的值,所以我认为您可以这样做:
if (response != null)
{
Func<TEntity, T> func = propertyExpression.Compile();
return func(response);
}如果您打算对表达式执行其他操作(比如获取属性的名称),那么您需要决定是否支持不直接引用属性的表达式,并为此添加处理程序。
发布于 2016-10-26 14:25:41
只需执行Lambda表达式即可:
if (response != null)
{
return propertyExpression.Compile().Invoke(response);
}https://stackoverflow.com/questions/40263509
复制相似问题