【问题标题】:C# Imap client - Use of expression treesC# Imap 客户端 - 表达式树的使用
【发布时间】:2011-09-08 18:21:29
【问题描述】:
我目前正在开发自己的.net imap api,我想在 imap SEARCH 命令中加入表达式树的使用,例如:
client.Search(m => m.DateRecieved < DateTime.Now)
应该转换成下面的
imap1 SEARCH SENTBEFORE 8-Sep-2011
由于我不熟悉表达式树,是否可以将该 func 参数转换为指定的命令?我知道我必须检查“m”的每个属性并检查什么是什么,但我不太确定从哪里开始。
谢谢!
【问题讨论】:
标签:
c#
lambda
imap
expression-trees
【解决方案1】:
开始定义你的搜索函数(假设 m 是一个名为 Splog 的类):
void Search (Expression<Func<Splog, bool>> searchExpression)
然后乐趣就开始了。
然后你就可以做事了:
string comparison= "";
string compare1= "";
string compare2 = "";
if ( searchExpression.Body is BinaryExpression ) // Ensure the expression is a comparison..
{
if ( searchExpression.Body.NodyType == ExpressionType.LessThan )
comparison = "SENTBEFORE";
else if ( searchExpression.Body.NodyType == ExpressionType.GreaterThan )
comparison = "SENTAFTER";
else if ( searchExpression.Body.NodyType == ExpressionType.Equal )
comparison = "EQUALS";
// Then evaluate the left and right portions.
if ( ( searchExpression.Body as BinaryExpression ).Left is MemberExpression )
compare1 = ( ( searchExpression.Body as BinaryExpression ).Left as MemberExpression).Member.Name;
if ( ( searchExpression.Body as BinaryExpression ).Right is MemberExpression )
compare2 = ( ( searchExpression.Body as BinaryExpression ).Right as MemberExpression).Member.Name;
}
Console.WriteLine ( compare1 + " " + comparison + " " + compare2 );
注意
这只是为了让您入门。事情很快变得复杂起来。您必须牢记以下几点:
表达式中的任何内容都不会被评估。因此,在您的示例中,如果您传递表达式 x < DateTime.Now,则 DateTime.Now 不会评估为日期。您将获得 DateTime 的 Now 属性的 PropertyExpression。您需要满足这一点并进行评估以获取当前日期。
该示例假设您有一个简单的二进制比较。它不适合像(m.DateReceived < DateTime.Now && m.Client == "Spog" ) || m.Ooofgle > 22932 这样更复杂的比较
要处理像这样更复杂的场景,您应该确保您的方法递归地沿着树向下工作以构建您的表达式。这很有趣,也是很好的锻炼。
通读Expression documentation。