【问题标题】:Using reflection to retrieve a value from a list使用反射从列表中检索值
【发布时间】:2014-04-04 12:57:10
【问题描述】:

我有一个从 azure 移动服务检索表的简单方法。

public static async List<T>GetDataFromListTable<T>()
{
    var data = await MobileService.GetTable<T>().ToListAsync();
    return data.Count != 0 ? data : null;
}

这很好用。

我想要做的是另一种方法,它采用从服务返回的参数名称并返回该参数的值。到目前为止我有这个

public static async Task<T> GetDataFromTable<T>(string paramName)
    {
        var k = Activator.CreateInstance(typeof(T));
        var members = typeof(T).GetProperties().Select(t=>t.Name).ToList();
        if (!members.Contains(paramName))
            return (T)k;
        var mn = typeof(T).GetProperties()[members.IndexOf(paramName)];
        var data = GetDataFromListTable<T>();
        var retval = data.Select(t => t.mn);
    }

问题显然是我不能进行 Linq 查询,因为 T 不包含 mn。我也不能用

var retval = data.Select(t=>t.paramName);

因为 paramname 只是类中成员的字符串表示形式。

简而言之……

方法1有参数名,从方法2中获取一个列表。从方法2返回的列表中,找到参数名并返回相关值。

有没有办法做我想做的事?

【问题讨论】:

标签: c# linq generics azure


【解决方案1】:

你可以这样做:

var retval = data.Select(t => mn.GetGetMethod().Invoke(t, null));

var retval = data.Select(t => mn.GetValue(t, null));

你也可以用这样的方式来简化你的代码(未经测试,抱歉):

public static async Task<T> GetDataFromTable<T>(string paramName)
{
    var k = Activator.CreateInstance(typeof(T));
    var mn = typeof(T).GetProperty(paramName);

    if (mn == null)
        return (T)k;

    var data = GetDataFromListTable<T>();
    var retval = data.Select(t => mn.GetGetMethod().Invoke(t, null));

    ...
}

【讨论】:

  • 不错的答案。我认为这是可能的,但在此之前我从未真正涉足过反思——它有点强大!
  • 不应该GetDataFromTable&lt;T&gt;() 实际上返回一些东西吗? ;-)
  • 这取决于你是否希望它编译我猜 ;)
【解决方案2】:

我认为使用表达式树会更方便,因为您正在使用集合。您的方法签名需要合并TTResult 类型,因为它使用的是Select,它返回一个IEnumerable&lt;TResult&gt;

public static async Task<IEnumerable<TResult>> SelectData<T, TResult>(
    string propertyName
)
{
    if(string.IsNullOrWhiteSpace(propertyName))
    {
        return Enumerable.Empty<TResult>();
    }

    var dataTask = GetTableData<T>();

    var tType = Expression.Parameter(typeof(T), "t");
    var property = Expression.Property(tType, propertyName);
    var selectExpression =
        Expression.Lambda<Func<T, TResult>>(property, tType)
                  .Compile();
    return (await dataTask).Select(selectExpression);
}

【讨论】:

    【解决方案3】:

    这样不行吗

     var retval =  data.Select(t => mn.GetValue(t, null));
    

    【讨论】:

      猜你喜欢
      • 2010-09-17
      • 1970-01-01
      • 2016-03-15
      • 2013-06-25
      • 1970-01-01
      • 1970-01-01
      • 2012-05-29
      • 1970-01-01
      • 2017-04-27
      相关资源
      最近更新 更多