How to make multiplication operator (*) behave as short-circuit?

c#, operator-overloading, short-circuiting

Solution

The problem with your `MyDouble` wrapper class is that you use it by calling `longOperation` directly. As `*` is not short circuiting, it will be called directly.

Instead, you could just make your wrapper accept a `Func<double>` as the second parameter instead of the double value itself. So it would work like the `ShortCircuitMultiply` function:

public static MyDouble operator *(MyDouble left, Func<double> right)
{
    return Math.Abs(left.value) < epsilon ? new MyDouble(0) : new MyDouble(left.value * right());
}

Then you would use it like this:

MyDouble x = 0;
Console.WriteLine(x * LongOperation);

And even chaining works:

MyDouble x = 5;
Console.WriteLine(x * OperationReturingZero * LongOperation);

Full example

class Program
{
    static void Main()
    {
        MyDouble x = 0;
        Console.WriteLine(x * LongOperation);

        MyDouble y = 5;
        Console.WriteLine(y * OperationReturningZero * LongOperation);

        Console.ReadLine();
    }

    private static double LongOperation()
    {
        Console.WriteLine("LongOperation");
        return 5;
    }

    private static double OperationReturningZero()
    {
        Console.WriteLine("OperationReturningZero");
        return 0;
    }
}

class MyDouble
{
    private static double epsilon = 0.00000001;
    private double value;

    public MyDouble(double value)
    {
        this.value = value;
    }

    public static MyDouble operator *(MyDouble left, Func<double> right)
    {
        Console.WriteLine("* (MyDouble, Func<double>)");
        return Math.Abs(left.value) < epsilon ? new MyDouble(0) : new MyDouble(left.value * right());
    }

    public static MyDouble operator *(MyDouble left, MyDouble right)
    {
        Console.WriteLine("* (MyDouble, MyDouble)");
        return new MyDouble(left.value * right.value);
    }

    public static implicit operator double(MyDouble myDouble)
    {
        Console.WriteLine("cast to double");
        return myDouble.value;
    }

    public static implicit operator MyDouble(double value)
    {
        Console.WriteLine("cast to MyDouble");
        return new MyDouble(value);
    }
}

Output:

cast to MyDouble
* (MyDouble, Func<double>)
cast to double
0
cast to MyDouble
* (MyDouble, Func<double>)
OperationReturningZero
* (MyDouble, Func<double>)
cast to double
0

Problem

I have lots of computations, specially multiplication, where first part is sometimes zero and I don't want to evaluate second operand in that case. There are at least two short-circuit operators in C#: `&&` and `||` which evaluate second operand only if necessary. I want to achieve similar behavior with multiplication operator. In .net you can't overload `&&` operator directly, but you can overload `&` and `false` operators, so you can use your extension points to change behavior of short-circuit operator. You can find more details at this article C# operator overloading: the ‘&&’ operator Is there any means to achieve this or similar behavior for multiplication operator? This is a pure syntax question, because implementation is very simple. Next method achieves exactly what I want in terms of functionality: ``` public static double ShortCircuitMultiply(double val, Func<double> anotherValue) { var epsilon = 0.00000001; return Math.Abs(val) < epsilon ? 0 : val * anotherValue(); } ``` Note: this implementation is not full: in C# if you multiply `0.0` with `Double.NaN` or `Double.NegativeInfinity` or `Double.PositiveInfinity`, you'll get `NaN`, but in terms of `ShortCircuitMultiply` - only zero. Let's ignore this detail and it's really irrelevant in my domain. So now if I call it as `ShortCircuitMultiply(0.0, longOperation)` where `longOperation` is `Func<double>`, last term won't be evaluated and result of an operation will be effectively zero. The problem is, as I already stated, I would have lots of `ShortCircuitMultiply` calls and I want to make code more readable. I want code to be similar to `0.0 * longOperation()` if that is possible. Another note: I've tried to build wrapper on `double` and create implicit casting to double and also overload `*` operator. I understand, that this is probably redundant: I wanted to acheive readability, but trying to build yet another wrapper. Anyway, next code demonstrates my intent: ``` class MyDouble { double value; public MyDouble(double value) { this.value = value; } public static MyDouble operator *(MyDouble left, MyDouble right) { Console.WriteLine ("* operator call"); return new MyDouble(left.value * right.value); } public static implicit operator double(MyDouble myDouble) { Console.WriteLine ("cast to double"); return myDouble.value; } public static implicit operator MyDouble(double value) { Console.WriteLine ("cast to MyDouble"); return new MyDouble(value); } } ``` Now if I go with: ``` MyDouble zero = 0; Console.WriteLine (zero * longOperation()); //longOperation is still Func<double> ``` I've receive: ``` cast to MyDouble called longOperation <-- want to avoid this (it's printed from longOperation body) cast to double cast to MyDouble * operator call cast to double 0 ``` But as you can see, `longOperation` is evaluated long before overloaded operator is called, and I can't substitute one of the parameters with `Func` or `Expression` to make it lazy.

Original source