English 中文(简体)
结合表述与运营商和公司
原标题:Combining expression with operator &&
  • 时间:2011-11-23 14:52:52
  •  标签:
  • c#
  • lambda

I have class that works a bit like the Linq To Sql Where clause.

它从一个陈词树上建立了一系列行动。

The expression tree is an Expression<Func<bool>> (i.e. a lambda without arguments that returns a bool)

conditionBuilder.BuildCondition(() => x != 3 && y != 5);

The class works fine for normal expressions like the example above but now I need the functionality to combine expressions.

I have added And, Or methods like

var exp1 = () => x != 3;
var exp2 = () => y != 5;
var exp = ConditionBuilder.And(exp1, exp2);

但它在结合若干表述时变得复杂。

我谨写信。

var exp = exp1 && exp2;

but since I can t directly overload operator && I need to find some other solution. The tricky part is that resulting operations does not have a boolean overload for the bitwise operators. i.e. the result of exp1 & exp2 is int and not bool. (I can get around this by adding != 0)

So my questions now are:

  • Will it be confusing if I let operator & be a logical expression (i.e. AndAlso)?
  • operator && will work if I overload & / true / false but that will also create an implicit boolean conversion. I know implicit boolean conversion is something you want to avoid in C++ but I am not sure how it matters i C#. Also, should the overridden true and false evaulate the expression? (i.e. what should if (exp1) do?)

Edit: I already have working code like this:

public class ConditionBuilder
{
    private readonly Expression<Func<bool>> _filter;

    public ConditionBuilder(Expression<Func<bool>> filter) {
        _filter = filter;
    }

    public static ConditionBuilder And(ConditionBuilder left, ConditionBuilder right) {
        return new ConditionBuilder(Expression.Lambda<Func<bool>>(Expression.AndAlso(left._filter.Body, right._filter.Body)));
    }

    public static ConditionBuilder Or(ConditionBuilder left, ConditionBuilder right) {
        return new ConditionBuilder(Expression.Lambda<Func<bool>>(Expression.OrElse(left._filter.Body, right._filter.Body)));
    }
}

Edit 2 to clarify the questions.

这些用语改为另一种格式。 例如,() => ConditionsBuilder。 Int Field(123) = 5 改为123 EQ 5 。 (真正的形式是别的,但你们还是有这种想法)

问题在于,其他方式的拖网对双向操作者而言具有超重负荷。 这意味着:(>) => real & false被转换成True BITAND False,因其返回的不是纯洁而没有有效表述。

如果我超负荷工作,就是指AndAlso

exp1 & exp2

有效表述,

() => x != 3 & y != 5

不是。

My second question was if having an implicit conversion to bool causes problems in C# like it does in C++.

问题回答

我将超载<代码>&营运人。 这不是混淆,因为<代码>&可视具体情况合乎逻辑或两倍。

超载<代码>& 运营商必须使用一个包装类别(例如 ConditionsBuilder),供您超负荷运营商使用。

您可以看到一个全例超载各种运营商,包括&在真实操作者文件中,


采用<条码>的简便实例:显示超载<条码>和>;操作员。

void Main ()
{
    int x = 1;
    int y = 1;

    var exp1 = new ConditionBuilder (() => x != 3);
    var exp2 = new ConditionBuilder (() => y != 5);
    var exp3 = exp1 & exp2;

    Console.WriteLine (exp3.Execute ());
}

public class ConditionBuilder
{
    private readonly Expression<Func<bool>> _filter;

    public ConditionBuilder(Expression<Func<bool>> filter) {
        _filter = filter;
    }

    public bool Execute() {
        return _filter.Compile()();
    }

    public static ConditionBuilder And(ConditionBuilder left, ConditionBuilder right) {
        return new ConditionBuilder(Expression.Lambda<Func<bool>>(Expression.AndAlso(left._filter.Body, right._filter.Body)));
    }

    public static ConditionBuilder Or(ConditionBuilder left, ConditionBuilder right) {
        return new ConditionBuilder(Expression.Lambda<Func<bool>>(Expression.OrElse(left._filter.Body, right._filter.Body)));
    }

    public static ConditionBuilder operator & (ConditionBuilder left, ConditionBuilder right) {
        // Note this could confuse users for the problem discussed below.
        // Consider using Expression.And instead of AndAlso
        return ConditionBuilder.And(left, right);
    }

    public static ConditionBuilder operator | (ConditionBuilder left, ConditionBuilder right) {
        // Note this could confuse users for the problem discussed below.
        // Consider using Expression.Or instead of OrElse
        return ConditionBuilder.Or(left, right);
    }
}

我将仔细使用短路操作员(AndAlso,Else with & and ; Bar(),如果Foo回报不实的酒吧将<>>>>>>>/em>被大多数用户称出。


Alternative

Change ConditionBuilder s And/Or methods to be instance members and only take the right hand side as an argument.

public ConditionBuilder And(ConditionBuilder right) {
    return new ConditionBuilder(Expression.Lambda<Func<bool>>(Expression.AndAlso(_filter.Body, right._filter.Body)));
}

由此产生了一种合成物,例如var util3 = util1.And(exp2);,与原样,链条将合理完善exp1.And(exp2)。 And(exp3)

exp1.Or(exp2)。 和(exp3)请见(exp1 CTOC2) & 编号:,而不是exp1 >(exp2 & 编号3)。 可以通过下列明确母体避免这种情况:(exp1.Or(exp2))。


Problem with supporting &&

支持<代码>&& 您将需要支持以下各条:<代码>true和>>;false的操作者,其含义是汇编和执行该表述。

public static bool operator true (ConditionBuilder left) {
    return left.Execute();
}

public static bool operator false (ConditionBuilder left) {
    return !left.Execute();
}

在与LinqPAD测试结果时,通过<条码>var util3 = 权宜之计1 && 权码/代码低于理想结果。

  1. exp1 had to be executed immediately to resolve the short-circuit.
  2. When exp1 was true the resulting expression was equivalent to:
    var exp3 = () => x != 3 && y != 5
  3. When exp1 was false the resulting expression was equivalent to:
    var exp3 = () => x != 3




相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签