如何获取属性名称并比较表达式中的值?

时间:2017-05-19 18:18:27

标签: c# reflection properties expression func

我们在工作中使用过滤器

  

表达< Func< T,bool> >

我们使用的方法如下:

  

元组<字符串,字符串,对象> SplitFilter<人>(x => x.SurName =="史密斯");

我需要创建一个表达式< Func< T,bool> >作为一个参数,如上所示,并将其分为3个值,一个字符串" SurName"对于该属性,一个字符串" =="表示相等比较,以及字符串" Smith"对于要比较的价值。

我设法得到字符串" SurName"从中可以看出,我不知道如何确定比较的类型(相等)或比较值(" Smith")

2 个答案:

答案 0 :(得分:0)

从这里采取:https://www.codeproject.com/Questions/322211/Parsing-a-linq-expression

static readonly List<int> data = new List<int>() { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

static IEnumerable<int> SelectData(Expression<Predicate<int>> selector)
{
    ParameterExpression param = (ParameterExpression)selector.Parameters[0];
    BinaryExpression operation = (BinaryExpression)selector.Body;
    ParameterExpression left = (ParameterExpression)operation.Left;
    ConstantExpression right = (ConstantExpression)operation.Right;

    Console.WriteLine("Decomposed expression: {0} => {1} {2} {3}",
                      param.Name, left.Name, operation.NodeType, right.Value);
    //...

    return from d in data where selector.Compile()(d) select d;
}

static void Main(string[] args)
{
    Console.WriteLine("data = {0}", string.Join(",", SelectData(d=>d>4)));
}

Decomposed expression: d => d GreaterThan 4
data = 5,6,7,8,9

答案 1 :(得分:0)

前几天工作了。最终目标实际上是对这些值进行哈希处理,因此我们可以从每个过滤器中获取哈希值。对于未来的人们,我最终如何将其分解如下:

private int HashFilter<T>( Expression<Func<T, bool>> filter ) {
  var param = filter.Parameters[0];
  var operation = filter.Body as BinaryExpression;
  var leftParameter = operation.Left as ParameterExpression;
  var leftIndex = operation.Left as MemberExpression;
  var type = operation.Left.GetType().FullName;
  var rightConstant = operation.Right as ConstantExpression;
  object result;
  if ( rightConstant == null ) {
    var rightMember = operation.Right as MemberExpression;
    result = Expression.Lambda( rightMember ).Compile().DynamicInvoke();
  }
  else {
    result = rightConstant.Value;
  }
  var value = result as string;
  var leftHashCode = leftParameter != null ? leftParameter.Name.GetStableHashCode() : leftIndex.Member.Name.GetStableHashCode();
  var operationHashCode = operation.NodeType.ToString().GetStableHashCode();
  unchecked {
    if ( value != null ) {
      return leftHashCode | operationHashCode | value.GetStableHashCode();
    }
    else {
      return leftHashCode | operationHashCode | result.GetHashCode();
    }
  }
}

GetStableHashCode是以下扩展哈希算法(因为哈希一个字符串使用引用,所以“Hi”.GetHashCode()==“Hi”.GetHashCode()永远不会评估为true,但这个GetStableHashCode会。

public static int GetStableHashCode( this string str ) {
  unchecked {
    int hash1 = (5381 << 16) + 5381;
    int hash2 = hash1;

    for ( int i = 0; i < str.Length; i += 2 ) {
      hash1 = ((hash1 << 5) + hash1) ^ str[i];
      if ( i == str.Length - 1 )
        break;
      hash2 = ((hash2 << 5) + hash2) ^ str[i + 1];
    }

    return hash1 + (hash2 * 1566083941);
  }
}