最有效的方法来测试拉姆达前pressions平等 [英] Most efficient way to test equality of lambda expressions
本文介绍了最有效的方法来测试拉姆达前pressions平等的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
给定一个方法签名:
公共BOOL AreTheSame< T>(防爆pression< Func键< T,对象>> EXP1,防爆pression< Func键< T,对象>> EXP2 )
什么是最有效的方式说,如果两位前pressions是一样的吗?这只需要简单的前pressions工作,我的意思是所有的将是支持将是简单MemberEx pressions,如c => c.ID。
一个例子电话可能是:
AreTheSame<使用者>(U1 => u1.ID,U2 => u2.ID); - >将返回true。
解决方案
嗯...我想你不得不解析树,检查每个的节点类型和成员。我敲了一个例子...
使用系统;
使用System.Linq.Ex pressions;
Test类{
公共字符串美孚{搞定;组; }
公共字符串酒吧{搞定;组; }
静态无效的主要()
{
布尔TEST1 = FuncTest&所述;试验> .FuncEqual(X => x.Bar,Y => y.Bar),
TEST2 = FuncTest&所述;试验> .FuncEqual(X => x.Foo,Y => y.Bar);
}}
//这个只存在,使其更容易调用,即让我可以使用FuncTest< T>同
//通用型推理;如果使用双重泛型方法,你需要指定
//两个参数,这是一种痛苦...
静态类FuncTest< TSource>
{
公共静态布尔FuncEqual< TValue>(
防爆pression<&Func键LT; TSource,TValue>> X,
防爆pression<&Func键LT; TSource,TValue>> Y)
{
返回FuncTest.FuncEqual&下; TSource,TValue>(X,Y);
}
}
静态类FuncTest {
公共静态布尔FuncEqual< TSource,TValue>(
防爆pression<&Func键LT; TSource,TValue>> X,
防爆pression<&Func键LT; TSource,TValue>> Y)
{
返回例pressionEqual(X,Y);
}
私人静态布尔防爆pressionEqual(前pression X,防爆pression Y)
{
//处理简单的情况下,第一...
如果(的ReferenceEquals(X,Y))返回true;
如果(X == NULL ||ÿ== NULL)返回false;
如果(x.NodeType!= y.NodeType
|| !x.Type = y.Type)返回false; 开关(x.NodeType)
{
案例防爆pressionType.Lambda:
返回前pressionEqual(((LambdaEx pression)X)。体,((LambdaEx pression)Y)。体);
案例防爆pressionType.MemberAccess:
MemberEx pression MEX =(MemberEx pression)X,MEY =(MemberEx pression)Y;
返回mex.Member == mey.Member; //应该真正考验下游EX pression
默认:
抛出新NotImplementedException(x.NodeType.ToString());
}
}
}
Given a method signature:
public bool AreTheSame<T>(Expression<Func<T, object>> exp1, Expression<Func<T, object>> exp2)
What would be the most efficient way to say if the two expressions are the same? This only needs to work for simple expressions, by this I mean all that would be "supported" would be simple MemberExpressions, eg c => c.ID.
An example call might be:
AreTheSame<User>(u1 => u1.ID, u2 => u2.ID); --> would return true
解决方案
Hmmm... I guess you'd have to parse the tree, checking the node-type and member of each. I'll knock up an example...
using System;
using System.Linq.Expressions;
class Test {
public string Foo { get; set; }
public string Bar { get; set; }
static void Main()
{
bool test1 = FuncTest<Test>.FuncEqual(x => x.Bar, y => y.Bar),
test2 = FuncTest<Test>.FuncEqual(x => x.Foo, y => y.Bar);
}
}
// this only exists to make it easier to call, i.e. so that I can use FuncTest<T> with
// generic-type-inference; if you use the doubly-generic method, you need to specify
// both arguments, which is a pain...
static class FuncTest<TSource>
{
public static bool FuncEqual<TValue>(
Expression<Func<TSource, TValue>> x,
Expression<Func<TSource, TValue>> y)
{
return FuncTest.FuncEqual<TSource, TValue>(x, y);
}
}
static class FuncTest {
public static bool FuncEqual<TSource, TValue>(
Expression<Func<TSource,TValue>> x,
Expression<Func<TSource,TValue>> y)
{
return ExpressionEqual(x, y);
}
private static bool ExpressionEqual(Expression x, Expression y)
{
// deal with the simple cases first...
if (ReferenceEquals(x, y)) return true;
if (x == null || y == null) return false;
if ( x.NodeType != y.NodeType
|| x.Type != y.Type ) return false;
switch (x.NodeType)
{
case ExpressionType.Lambda:
return ExpressionEqual(((LambdaExpression)x).Body, ((LambdaExpression)y).Body);
case ExpressionType.MemberAccess:
MemberExpression mex = (MemberExpression)x, mey = (MemberExpression)y;
return mex.Member == mey.Member; // should really test down-stream expression
default:
throw new NotImplementedException(x.NodeType.ToString());
}
}
}
这篇关于最有效的方法来测试拉姆达前pressions平等的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文