[英]Force C# compiler to use non-generic method overload with Linq Expression parameter
我有重載的方法,一種泛型和一種非泛型。 這兩種方法都將Linq表達式作為單個參數接收:
public void Test(Expression<Action<char>> expr) {}
public void Test<T>(Expression<Func<char, T>> expr) {}
現在考慮以下調用:
var sb = new StringBuilder();
Test(c => sb.Append(c));
因為Append()
方法確實(不幸地)返回StringBuilder
所以編譯器將選擇通用方法。 但是,就我而言,我絕對需要調用非泛型方法。
以下變通辦法顯示代碼沒有類型問題(非泛型調用將完全有效):
Expression<Action<char>> expr = c => sb.Append(c);
Test(expr);
但是,我寧願不聲明具有顯式類型的變量,而是以某種方式使編譯器選擇非泛型方法(就像我可以告訴它使用具有顯式類型參數的泛型方法一樣)。
您可以在SharpLab.io上玩這個游戲 。
這似乎是一種解決方法(因為是這樣),但是您可以使用命名參數來闡明您正在調用的方法。
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>()");
}
當您需要非通用版本時,只需在參數列表中提供參數名稱action:
。
static public void Main()
{
var sb = new StringBuilder();
Test(action: c => sb.Append(c) );
Test(func: c => sb.Append(c) );
}
輸出:
Test()
Test<T>()
這可能比寫出表達式強制轉換更容易使用。
您可以使用空方法吞下sb.Append的返回值。 我不會將其稱為解決方法,因為它只能使編譯器正常工作,但也不是完全干凈漂亮。
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>()");
}
當將輸出包裝為NoValue時,編譯器正確地將其視為Action,而不是函數。
static public void Main()
{
var sb = new StringBuilder();
Test(c => NoValue(sb.Append(c)) );
Test(c => sb.Append(c) );
}
輸出:
Test()
Test<T>()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.