-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Description
Description
As described on MSDN, in DLR operations AndAlso and OrElse represent pairs of IsFalse/And and IsTrue/Or. This is becoming a problem when I'm trying to implement some zero/non-zero boolean logic.
For example, I have some dynamic object over integer. Zero value is false, non-zero is true. In c++ it works like this:
int a = 10;
int b = 20;
cout << (a && b); // out '1', coz 10 and 20 both are non-zero values
cout << (a & b); // out '0', coz it's a result of bitwise andWith current implementation of DLR I can't implement such behavior coz when I binding binary operation, I got And/Or operation type instead of expected AndAlso/OrElse. So I dont know, was it logical or bitwise operation.
Reproduction Steps
Define this simple class:
public sealed class MetaUInt32 : DynamicObject
{
private readonly uint value;
public MetaUInt32(uint value)
{
this.value = value;
}
public override bool TryUnaryOperation(UnaryOperationBinder binder, out object? result)
{
if (binder.Operation == ExpressionType.IsFalse)
{
result = (value == 0u);
return true;
}
else
{
return base.TryUnaryOperation(binder, out result);
}
}
public override bool TryBinaryOperation(BinaryOperationBinder binder, object arg, out object? result)
{
if (arg is MetaUInt32 m && binder.Operation is ExpressionType.And)
{
result = new MetaUInt32(value & m.value);
return true;
}
else
{
return base.TryBinaryOperation(binder, arg, out result);
}
}
}And then use it like this:
dynamic a = new MetaUInt32(10);
dynamic b = new MetaUInt32(20);
var c = a && b;Expected behavior
Variable c must be instance of MetaUInt32 over 1, because a and b are non-zero values (10 and 20).
Actual behavior
Variable c is instance of MetaUInt32 over 0, because it's a result of bitwise and over 10 and 20.
Regression?
No response
Known Workarounds
As workaround, I can implement casting of MetaUInt32 to boolean and then make boolean binary operation over cast results, like this:
dynamic c = new MetaUInt32((bool)a && (bool)c ? 1 : 0);It's not too hard to do, but if your dynamic class also implements bitwise logic, you must keep in mind, that boolean binary logic works correctly only if you cast your object to boolean first.
Also it's becoming a problem when you are working with dynamic expressions (System.Linq.Expressions.Expression.Dynamic). If you'are implementing binary operation, you must have special case for AndAlso/OrElse operations, because them are not supported by BinaryOperationBinder.
Configuration
No response
Other information
No response