"+" => ((Func<int>)(() => {
Log("addition");
return a + b;
}))(),
This is incredibly ugly. Why couldn’t it be “+” => {stuff} "+" => ((Func<int>)(() => {
Log("addition");
return a + b;
}))(),
This is incredibly ugly. Why couldn’t it be “+” => {stuff}What he's doing is creating an anonymous function which takes no parameters and returns an int. That's what a Func<int> is, and then he is executing that function, that's the () bit after }))
He could write it nicer as:
"+" => Add(),
Where he defines add as int Add() => a + b;
He's just doing too much inline, 99% of C# developers would not write code as he has done there.Its' the bloggers code style that is the problem here, not the new switch syntax. Although he probably did it to make the example more self contained and terse.
It's two short lines.
The problem is that he's writing a small but more than one line bit of code, so the overhead of the anonymous function is just as big as the code itself, and arguably more complex.
T Log<T>(string msg, Func<T> func) {
Log(msg);
return func();
}
var result = operation switch {
"+" => Log("addition", () => a + b),
"-" => Log("subtraction", () => a - b),
"/" => Log("division", () => a / b),
_ => throw new NotSupportedException()
};
This is shorter, cleaner, and how most folks would actually write something like this, I imagine. T Log<T>(string msg, T result) {
Log(msg);
return result;
}
var result = operation switch {
"+" => Log("addition", a + b),
"-" => Log("subtraction", a - b),
"/" => Log("division", a / b),
_ => throw new NotSupportedException()
};
You already have a lambda for calling Log(), no need for a second to call the inner function. This does change the order of evaluation though.I just mention it for academic interest. To be honest, I find the idea of passing a parameter to Log() (whether it's the value or the function) that your don't actually want logged, so that you can shoehorn two statements into an expression, abhorrent. Just write the two statements out! I think an old-fashioned switch statement is the right tool here.
You've basically reimplemented Haskell's Debug.Trace[0] :)
The difference is of course that Haskell doesn't really have statements in the same way that C# does, so in Haskell it's nescessary to turn the log/trace-function into an identity function after you've applied the message-string.
I agree that it is ugly, and in any serious project I would use a proper logging setup, but I almost feel like the ugliness is a feature not a bug. It's like an extra cost when doing debug-by-print, which at least seem to keep me more mindful about cleaning up after myself.
[0] http://hackage.haskell.org/package/base-4.12.0.0/docs/Debug-...