【问题标题】:Using reflection to obtain values based on a specific query condition使用反射根据特定查询条件获取值
【发布时间】:2014-04-09 12:31:03
【问题描述】:

我的问题与此处回答的问题略有不同 (Using reflection to retrieve a value from a list)

虽然此处批准的答案适用于选择,但我想对其进行扩展,以便我可以根据条件类型从查询中获取数据。目前,我改编的代码是这样的

 public static async Task<T> GetDataFromTable<T>(string paramName, string condition="")
    {
        var k = Activator.CreateInstance(typeof(T));
        var mn = typeof(T).GetProperty(paramName);
        var tc = typeof(T).GetProperty(condition);
        if (mn == null || !ftrackData.Online)
            return (T)k;
        var data = GetTableData<T>();
        if (!string.IsNullOrEmpty(paramName))
        {
            var retval = data.Select(t => mn.GetValue(t, null));
            return (T)retval;
        }
        else
            return (T)data.FirstOrDefault(t => mn.GetValue(t, null) > tc.GetType(t, null)).ToList();
    }

我希望最终返回中的“>”会根据传递到参数列表中的附加参数而改变。我知道我可以在 else 之后做一个简单的切换,但是有没有办法通过插入来改变条件?

【问题讨论】:

标签: c# c#-4.0 generics reflection


【解决方案1】:

您的代码实际上没有任何意义。 Select 扩展方法采用Func&lt;T, TResult&gt;,这意味着返回类型应为IEnumerable&lt;TResult&gt;,而您将其指定为T

在您的问题中,您想以相同的方法执行SelectFirstOrDefault,但这是不可能的,因为结果类型会有所不同。

Select:

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);
}

FirstOrDefault:

public static async Task<T> FirstOrDefaultData<T>(
    string propertyName,
    string conditionName,
    Func<MemberExpression, MemberExpression, BinaryExpression> comparer
)
{
    if(string.IsNullOrWhiteSpace(propertyName) ||
       string.IsNullOrWhileSpace(conditionName) ||
       comparer == null
    {
        return default(T);
    }

    var dataTask = GetTableData<T>();

    var tType = Expression.Parameter(typeof(T), "t");
    var property = Expression.Property(tType, propertyName);
    var condition = Expression.Property(tType, conditionName);
    var binaryExpression =
        Expression.Lambda<Func<T, bool>>(comparer(property, condition), tType)
                  .Compile();
    return (await dataTask).FirstOrDefault(binaryExpression);
}

用法:

public class Foo
{
    public string Bar { get; set; }
    public bool Flag { get; set; }
}

var bars = SelectData<Foo, string>("Bar");
var foo = FirstOrDefaultData<Foo>("Bar",
                                  "Flag",
                                  (p, c) => Expression.GreaterThan(p, c));

【讨论】:

  • 感谢您提供如此完整的答案 - 谢谢,解释了很多:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-27
  • 1970-01-01
  • 2020-12-14
  • 2023-03-05
  • 1970-01-01
相关资源
最近更新 更多