15

パラメータに基づいて型を返すコードをスタートアップ クラス (.net core 3.1) に追加しましたが、コンパイル時にエラーが発生します。

Sharplabで実行例を作成しました。スイッチ式に文字列またはその他のオブジェクトが含まれている場合、正常に実行されます。

作業例 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

PavelMarcのおかげで、以下が修正されました。

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()

                };
}
4

3 に答える 3

2

あなたは共分散の問題を扱っています。の戻り値の型は である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()
    };
}
于 2020-04-02T14:30:58.793 に答える