【发布时间】:2020-07-14 12:42:24
【问题描述】:
我在我的启动类(.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()
};
}
【问题讨论】:
-
如果
Handler1和Handler2有一个共同的基本类型/接口就可以了。 -
由于
DateTime可以向下转换为object,这是可行的,但我认为MyHandler2不会从MyHandler1继承,反之亦然。如果这两种类型有一个共同的基本类型,您可以使用它而不是var来为编译器提供足够的知识。 IE。MyHandlerBase handler = key switch { ... };. -
MyHandler1和MyHandler2是否共享一个共同的基本类型?也许用它代替var -
@MarcGravell 是的,它们都有 baseType 和接口。在sharplab中,我使用了BaseHandler/Ihandler,它解决了这个问题,但是当我在启动DI类中应用相同的更改时,它仍然给出错误。
-
也许
return (IHandler) key switch...?
标签: c# asp.net-core .net-core c#-8.0 switch-expression