在C#中创建泛型表达式生成方法

时间:2016-11-14 13:57:54

标签: c# reflection lambda

我正在使用多种方法构建IQueryable查询。这些方法有些复杂,但我想解决的问题可以如下提取和简化。我有两种方法

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>

<div ng-app="myApp" ng-controller="myCtrl as vm">

First Name: <input type="text" ng-model="vm.firstName" ng-keydown="vm.handleKeyDown($event)"><br>

</div>

我想要的是这个:

private Expression<Func<T, bool>> CreateExpressionA(string ValueA)
{
  return a => a.PropertyA.ToLower() == ValueA;
}

private Expression<Func<T, bool>> CreateExpressionB(string ValueB)
{
  return a => a.PropertyB.ToLower() == ValueB;
}

或类似的方法,这将允许我避免使用两个相同的方法,唯一的区别是在那里使用对象的属性。

是否可以以优雅的方式做到这一点?

3 个答案:

答案 0 :(得分:4)

您可以传入一个返回Func属性的选择器string

private Expression<Func<T, bool>> CreateExpression<T>(Func<T, string> selector, string value)
{
    return a => selector(a).ToLower() == value;
}

用法:

CreateExpression<MyType>(x => x.PropertyA, "thevalue");

答案 1 :(得分:1)

您可以使用反射,更准确地说是类PropertyInfo作为参数,但实现会更复杂。该方法可以实现如下。

private Expression<Func<T, bool>> CreateExpression(PropertyInfo iInfo, string Value)
{
    return a => (iInfo.GetPropertyValue(a) as string).ToLower() == ValueB;
}

但请注意,仅当属性类型为string时才会起作用,否则可能会使用其他类型参数。

答案 2 :(得分:0)

您可以做的是从头开始创建表达式:

private Expression<Func<T, bool>> CreateExpression(string propertyName, string value) {
    ParameterExpression param = Expression.Parameter(typeof(T));
    MemberExpression property = Expression.Property(param, propertyName);
    var valExpr = Expression.Constant(value);
    var body = Expression.Equal(property, valExpr);
    return Expression.Lambda<Func<T, bool>>(body, param);
}

致电:

var expression = CreateExpression<TypeOfA>("PropertyA", "ValueForPropertyA");

它有点偏离我的头脑,但我认为这至少应该让你开始。如果您需要帮助,请告诉我。