I have overloaded methods, one generic and one non-generic. The two methods both receive a Linq Expression as single parameter:
public void Test(Expression<Action<char>> expr) {}
public void Test<T>(Expression<Func<char, T>> expr) {}
Now consider the following invocation:
var sb = new StringBuilder();
Test(c => sb.Append(c));
The compiler will pick the generic method since the Append()
method does (unfortunately) return a StringBuilder
. However, in my case I absolutely need the non-generic method to be called.
The following workaround shows that there is no type issue with the code (the non-generic call would be perfectly valid):
Expression<Action<char>> expr = c => sb.Append(c);
Test(expr);
However, I'd prefer not to declare a variable with an explicit type and instead somehow get the compiler to pick the non-generic method (just like I could tell it to use the generic method with explicit type parameters).
You can play with this at SharpLab.io .
This may seem like a workaround (because it is), but you can used a named parameter to clarify which method you are calling.
static public void Test(Expression<Action<char>> action)
{
Console.WriteLine("Test()");
}
static public void Test<T>(Expression<Func<char, T>> func)
{
Console.WriteLine("Test<T>()");
}
When you want the non-generic version, just provide the parameter name action:
in the argument list.
static public void Main()
{
var sb = new StringBuilder();
Test(action: c => sb.Append(c) );
Test(func: c => sb.Append(c) );
}
Output:
Test()
Test<T>()
This might be easier to use than writing out the expression cast.
You can use an empty method to swallow the return value of sb.Append. I wouldn't call this a workaround, since it just makes the compiler work normally, but it isn't totally clean and pretty either.
static public void NoValue(object value) {}
static public void Test(Expression<Action<char>> action)
{
Console.WriteLine("Test()");
}
static public void Test<T>(Expression<Func<char, T>> func)
{
Console.WriteLine("Test<T>()");
}
When you wrap the output in NoValue, the compiler correctly sees this as an Action, not a function.
static public void Main()
{
var sb = new StringBuilder();
Test(c => NoValue(sb.Append(c)) );
Test(c => sb.Append(c) );
}
Output:
Test()
Test<T>()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.