[英]c# 8 switch expression: No best type was found for the switch expression
I have added a code in my startup class (.net core 3.1) to return the type based on parameter and I get compile-time errors.我在我的启动类(.net core 3.1)中添加了一个代码来返回基于参数的类型,我得到了编译时错误。
I have created a running example in sharplab .我在sharplab中创建了一个运行示例。 if switch expression contains the string or other objects it runs fine.如果 switch 表达式包含它运行良好的字符串或其他对象。
working example 1:工作示例1:
var x = key switch
{
"myhandler1" => "something",
"myhandler2" => "something else",
_ => "default case"
};
working example 2:工作示例2:
object obj = s switch {
"a" => new object(),
"b" => new DateTime(),
_ => throw new NotImplementedException()
};
Error example:错误示例:
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!");
}
}
original problem (needs fixing):原始问题(需要修复):
serviceCollection.AddTransient<Func<string, IHandler>>(sp => key =>
{
return key switch
{
Constants.Brand => sp.GetService<Handler1>(),
Constants.Series => sp.GetService<Handler2>(),
_ => throw new NotImplementedException()
};
}
found this link: https://github.com/dotnet/csharplang/issues/2728找到这个链接: https : //github.com/dotnet/csharplang/issues/2728
Thanks to Pavel and Marc , below is the fix:感谢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()
};
}
You should explicitly declare a type of handler, instead of var
您应该显式声明一种处理程序类型,而不是var
IHandler handler = key switch //or BaseHandler handler = key switch
{
"myhandler1" => new MyHandler1(),
"myhandler2" => new MyHandler2(),
_ => throw new NotImplementedException()
};
In your sharplab sample both handlers implement IHandler
interface and inherit BaseHandler
class, compiler simply doesn't know which type to use, you should tell it him explicitly在您的sharplab示例中,两个处理程序都实现了IHandler
接口并继承了BaseHandler
类,编译器根本不知道使用哪种类型,您应该明确地告诉他
interface IHandler { }
public class BaseHandler { }
public class MyHandler1 : BaseHandler, IHandler { }
public class MyHandler2 : BaseHandler, IHandler { }
The same is true for the dependency injection sample, you should explicitly declare a type (assuming that Handler1
and Handler2
implement IHandler
)依赖注入示例也是如此,你应该显式声明一个类型(假设Handler1
和Handler2
实现了IHandler
)
return key switch
{
Constants.Brand => sp.GetService<Handler1>(),
Constants.Series => (IHandler) sp.GetService<Handler2>(),
_ => throw new NotImplementedException()
};
You can do it only for one constant, compiler is smart enough to do the rest of job for you您只能为一个常量执行此操作,编译器足够聪明,可以为您完成其余工作
You're dealing with a covariance issue.您正在处理协方差问题。 You've specified that the return type of the Func
should be IHandler
, but this type param is invariant.您已指定Func
的返回类型应为IHandler
,但此类型参数是不变的。 As such, you have to actually return IHandler
, not just a class that implements it.因此,您必须实际返回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
is fussy - it wants things unambiguous, and it isn't obvious what type handler
should be here since MyHandler1
and MyHandler2
are different types; var
很挑剔 - 它希望事情明确无误,并且由于MyHandler1
和MyHandler2
是不同的类型,因此这里应该使用什么类型handler
并不明显; basically, pick some common base type or implemented interface from MyHandler1
and MyHandler2
, and use that instead of var
.基本上,从MyHandler1
和MyHandler2
选择一些常见的基类型或实现的接口,并使用它而不是var
。 At worst case, object
should suffice:在最坏的情况下, object
就足够了:
object handler = key switch
{
"myhandler1" => new MyHandler1(),
"myhandler2" => new MyHandler2(),
_ => throw new NotImplementedException()
};
The compiler won't attempt to do this itself.编译器不会尝试自己执行此操作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.