If I attempt to write two overloads of a method, one accepting an Expression<Func<T>>
parameter and another accepting a Func<T>
, I will get a compiler error on trying to call the method with a lambda expression because the two signatures create ambiguity. The following would be problematic, for example:
Method(() => "Hello"); // Is that a Func<string>,
// or is it an Expression<Func<string>>?
I get that. But I don't like the approach of just accepting an Expression<Func<string>>
, as this forces calling code to use a lambda expression. What if I want to be able to accept a method group as well?
My basis for asking this question is that I'm working on some code where I'd like to be able to write something like this:
Method(() => "Hello");
...and get output like this:
Executed '() => "Hello"' and got "Hello" back.
Meanwhile, I'd like to be able to do this as well:
Method(ReturnHello);
...and get output like this:
Executed 'ReturnHello' and got "Hello" back.
Is there any way to do what I'm trying to do here, without just using two different method names (e.g., ExpressionMethod
and FuncMethod
)? I realize that wouldn't be such a big deal; I'm just curious if there's another way.
An expression-bodied method consists of a single expression that returns a value whose type matches the method's return type, or, for methods that return void , that performs some operation.
LINQ introduced the new type called Expression that represents strongly typed lambda expression. It means lambda expression can also be assigned to Expression<TDelegate> type. The . NET compiler converts the lambda expression which is assigned to Expression<TDelegate> into an Expression tree instead of executable code.
You can overload a method to take either a Func<T>
or Expression<Func<T>>
but when you do that the automatic type determination fails so you need to explicitly define the types via casting. Like this:
public static void Test()
{
Test((Func<string>)(() => "helllo"));
Test((Expression<Func<string>>) (() => "hello"));
}
public static void Test<T>(Func<T> func)
{
}
public static void Test<T>(Expression<Func<T>> expression)
{
}
It's not pretty.
Maybe make one method with two named parameters with default values of null.
public static void Test<T>(Func<T> func = null, Expression<Func<T>> expression = null)
{
}
I know you miss the OR in this, but that's easy to check for in the method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With