C# 如何使用switch语句匹配传递的泛型类型和返回对象[]

C# 如何使用switch语句匹配传递的泛型类型和返回对象[],c#,generics,types,switch-statement,C#,Generics,Types,Switch Statement,我是一个有一点编程知识的测试人员,但我不能让它工作 我正在为集成测试创建一个基类(BaseIntegrationTest.cs)。它使用泛型来接受特定测试类所针对的DbContext和Repository类型。基类设置数据库上下文和连接,并创建相应存储库/控制器类的实例 class BaseIntegrationTest <TContext, TRepo> where TContext : DbContext where TRepo : BaseRepository

我是一个有一点编程知识的测试人员,但我不能让它工作

我正在为集成测试创建一个基类(BaseIntegrationTest.cs)。它使用泛型来接受特定测试类所针对的
DbContext
Repository
类型。基类设置数据库上下文和连接,并创建相应存储库/控制器类的实例

    class BaseIntegrationTest <TContext, TRepo> where TContext : DbContext where TRepo : BaseRepository
    {
        ...

    }

这个内部类给了我编译错误(如注释中所述),我尝试使用switch语句将泛型
RepoType
与列出的可能的存储库类类型进行比较,这些类型将被传递到
BaseIntegrationTest
。有什么方法可以使用clean switch功能来匹配泛型类型吗?

虽然@Matthew Watson的答案(在@General的帮助下)很聪明,解决了我的编译问题,但它并没有按预期运行
default(RepoType)
为基本类型返回正确类型的预期默认值,但为非基本类型返回
null
。这意味着switch语句与默认的
\uz=>newobject[]{}
匹配,而不管我通常传入哪个
RepoType

然而,我确实通过使用
nameof()
找到了一个适合我需要的解决方案

原始代码给我编译错误

    internal static object[] GetRepoConstrParamObjArr<DbContextType, RepoType>(
            DbContextType context,
            ILogger<RepoType> logger,
            SystemClock clock,
            CommonRepository commonRepo)
                where DbContextType : DbContext 
                where RepoType : BaseRepository
        => typeof(RepoType) switch
        {
            // these give compile error... CS0150: A constant value is expected
            typeof(DataRepositoryA) => new object[] { context, logger, clock, commonRepo },
            typeof(DataRepositoryB) => new object[] { context, logger, clock },
            // these give compile error... CS8121: An expression of type 'Type' cannot be handled by a pattern of type 'DataRepositoryC'
            DataRepositoryC         => new object[] { context, logger, clock, commonRepo },
            DataRepositoryD         => new object[] { context, logger, clock },
            _ => new object[] { }
        };

内部静态对象[]GetRepoConstructParamObjarr(
DbContextType上下文,
ILogger记录器,
系统时钟,
公共资源库(公共回购)
其中DbContextType:DbContext
其中RepoType:BaseRepository
=>类型(RepoType)开关
{
//这会导致编译错误…CS0150:应为常量值
typeof(DataRepositoryA)=>新对象[]{context,logger,clock,commonRepo},
typeof(DataRepositoryB)=>新对象[]{context,logger,clock},
//这些导致编译错误…CS8121:类型为“type”的表达式不能由类型为“DataRepositoryC”的模式处理
DataRepositoryC=>新对象[]{context,logger,clock,commonRepo},
DataRepositoryD=>新对象[]{context,logger,clock},
_=>新对象[]{}
};
按预期编译和运行的解决方案

    internal static object[] GetRepoConstrParamObjArr<DbContextType, RepoType>(
            DbContextType context,
            ILogger<RepoType> logger,
            SystemClock clock,
            CommonRepository commonRepo)
                where DbContextType : DbContext 
                where RepoType : BaseRepository
        => typeof(RepoType).Name switch
        {
            nameof(DataRepositoryA) => new object[] { context, logger, clock, commonRepo },
            nameof(DataRepositoryB) => new object[] { context, logger, clock },
            nameof(DataRepositoryC) => new object[] { context, logger, clock, commonRepo },
            nameof(DataRepositoryD) => new object[] { context, logger, clock },
            _                       => new object[] { }
        };

内部静态对象[]GetRepoConstructParamObjarr(
DbContextType上下文,
ILogger记录器,
系统时钟,
公共资源库(公共回购)
其中DbContextType:DbContext
其中RepoType:BaseRepository
=>typeof(RepoType).Name开关
{
nameof(datarepositoria)=>新对象[]{context,logger,clock,commonRepo},
nameof(DataRepositoryB)=>新对象[]{context,logger,clock},
nameof(DataRepositoryC)=>新对象[]{context,logger,clock,commonRepo},
nameof(DataRepositoryD)=>新对象[]{context,logger,clock},
_=>新对象[]{}
};

RepoType
是一个泛型类型参数,而不是
类型
类的实例(在正常约定下,它将被称为
TRepo
或类似名称以明确说明这一点)
switch
对象实例上的运算符,因此您需要编写
switch(typeof(RepoType))
。但是,switch语句的臂必须是常量表达式,并且
typeof(…)
不是常量,因此不能使用switch语句/表达式。您必须使用if/else if链,或使用
字典
    internal static object[] GetRepoConstrParamObjArr<DbContextType, RepoType>(
            DbContextType context,
            ILogger<RepoType> logger,
            SystemClock clock,
            CommonRepository commonRepo)
                where DbContextType : DbContext 
                where RepoType : BaseRepository
        => typeof(RepoType).Name switch
        {
            nameof(DataRepositoryA) => new object[] { context, logger, clock, commonRepo },
            nameof(DataRepositoryB) => new object[] { context, logger, clock },
            nameof(DataRepositoryC) => new object[] { context, logger, clock, commonRepo },
            nameof(DataRepositoryD) => new object[] { context, logger, clock },
            _                       => new object[] { }
        };