Клиент C # Imap - Использование деревьев выражений - PullRequest
1 голос
/ 08 сентября 2011

В настоящее время я занимаюсь разработкой своего собственного .net imap api. Я хочу включить использование деревьев выражений в команду imap SEARCH, например:

client.Search(m => m.DateRecieved < DateTime.Now)

следует преобразовать в следующее

imap1 SEARCH SENTBEFORE 8-Sep-2011

Поскольку я не знаком с деревьями выражений, возможно ли преобразовать этот параметр func в указанную команду? Я знаю, что мне придется проверять каждое свойство 'm' и проверять что к чему, но я не совсем уверен, с чего начать.

Спасибо!

1 Ответ

1 голос
/ 08 сентября 2011

Для начала определите вашу функцию поиска как (предположим, что 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 );

Примечание

Это только для начала. Вещи усложняются очень быстро. Вот некоторые вещи, которые вы должны иметь в виду:

  1. Ничто в выражении не оценивается. Так что в вашем примере, если вы передадите выражение x < DateTime.Now, DateTime.Now не будет оцениваться как Date. Вы передаете PropertyExpression для свойства Now свойства DateTime. Вам нужно учесть это и оценить, чтобы получить текущую дату.

  2. В примере предполагается, что у вас есть простое двоичное сравнение. Это не будет обслуживать более сложное сравнение, как (m.DateReceived < DateTime.Now && m.Client == "Spog" ) || m.Ooofgle > 22932

Чтобы обрабатывать более сложные сценарии, подобные этому, вы должны убедиться, что ваш метод рекурсивно работает вниз по дереву для построения вашего выражения. Это очень весело и хорошее упражнение.

Внимательно прочитайте документацию Expression .

...