[英]c# 8 switch expression: No best type was found for the switch expression
我在我的啟動類(.net core 3.1)中添加了一個代碼來返回基於參數的類型,我得到了編譯時錯誤。
我在sharplab中創建了一個運行示例。 如果 switch 表達式包含它運行良好的字符串或其他對象。
工作示例1:
var x = key switch
{
"myhandler1" => "something",
"myhandler2" => "something else",
_ => "default case"
};
工作示例2:
object obj = s switch {
"a" => new object(),
"b" => new DateTime(),
_ => throw new NotImplementedException()
};
錯誤示例:
interface IHandler { }
public class BaseHandler { }
public class MyHandler1: BaseHandler, IHandler { }
public class MyHandler2: BaseHandler, IHandler { }
class Program
{
static void Main(string[] args)
{
var key = "myhandler1";
var handler = key switch
{
"myhandler1" => new MyHandler1(),
"myhandler2" => new MyHandler2(),
_ => throw new NotImplementedException()
};
var x = key switch
{
"myhandler1" => "something",
"myhandler2" => "something else",
_ => "default case"
};
Console.WriteLine("Hello World!");
}
}
原始問題(需要修復):
serviceCollection.AddTransient<Func<string, IHandler>>(sp => key =>
{
return key switch
{
Constants.Brand => sp.GetService<Handler1>(),
Constants.Series => sp.GetService<Handler2>(),
_ => throw new NotImplementedException()
};
}
找到這個鏈接: https : //github.com/dotnet/csharplang/issues/2728
感謝Pavel和Marc ,以下是修復:
serviceCollection.AddTransient<Func<string, IHandler>>(sp => key =>
{
return key switch
{
Constants.Brand => (sp.GetService<Handler1>() as IHandler),
Constants.Series => (sp.GetService<Handler2>() as IHandler),
_ => throw new NotImplementedException()
};
}
您應該顯式聲明一種處理程序類型,而不是var
IHandler handler = key switch //or BaseHandler handler = key switch
{
"myhandler1" => new MyHandler1(),
"myhandler2" => new MyHandler2(),
_ => throw new NotImplementedException()
};
在您的sharplab示例中,兩個處理程序都實現了IHandler
接口並繼承了BaseHandler
類,編譯器根本不知道使用哪種類型,您應該明確地告訴他
interface IHandler { }
public class BaseHandler { }
public class MyHandler1 : BaseHandler, IHandler { }
public class MyHandler2 : BaseHandler, IHandler { }
依賴注入示例也是如此,你應該顯式聲明一個類型(假設Handler1
和Handler2
實現了IHandler
)
return key switch
{
Constants.Brand => sp.GetService<Handler1>(),
Constants.Series => (IHandler) sp.GetService<Handler2>(),
_ => throw new NotImplementedException()
};
您只能為一個常量執行此操作,編譯器足夠聰明,可以為您完成其余工作
您正在處理協方差問題。 您已指定Func
的返回類型應為IHandler
,但此類型參數是不變的。 因此,您必須實際返回IHandler
,而不僅僅是實現它的類。
serviceCollection.AddTransient<Func<string, IHandler>>(sp => key =>
{
return key switch
{
Constants.Brand => (IHandler)sp.GetService<Handler1>(),
Constants.Series => (IHandler)sp.GetService<Handler2>(),
_ => throw new NotImplementedException()
};
}
var
很挑剔 - 它希望事情明確無誤,並且由於MyHandler1
和MyHandler2
是不同的類型,因此這里應該使用什么類型handler
並不明顯; 基本上,從MyHandler1
和MyHandler2
選擇一些常見的基類型或實現的接口,並使用它而不是var
。 在最壞的情況下, object
就足夠了:
object handler = key switch
{
"myhandler1" => new MyHandler1(),
"myhandler2" => new MyHandler2(),
_ => throw new NotImplementedException()
};
編譯器不會嘗試自己執行此操作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.