使用通用返回类型打开类型

woo*_*gie 3 c# generics c#-7.0

我正在努力通过编写一些可以为我创建属性的帮助程序来使EF更容易进行单元测试.我有几个支持领域

private Mock<DbSet<Workflow>> mockedWorkFlows;
private Mock<DbSet<WorkflowError>> mockedWorkFlowErrors;
Run Code Online (Sandbox Code Playgroud)

我希望通用函数能够使用以下函数返回正确的支持字段

public Mock<DbSet<T>> Mocked<T>(T t) where T : class
{
   if ( (object)t is Workflow)
   {
       return mockedWorkFlows; //cannot Workflow to T
    }
}
Run Code Online (Sandbox Code Playgroud)

我想根据传递它的类型返回几个私有支持字段.

但是,即使我添加了类约束Workflow,我也会得到相同的错误.

我也试过打开t's类型,但也没有运气.除了object之外,几个支持字段的类型不共享共同的祖先.我正在尝试做什么?

Evk*_*Evk 6

如果我理解你的意图 - 你可以这样做:

// no need to pass instance of T - why?
public Mock<DbSet<T>> Mocked<T>() where T : class
{
    if (typeof(T) == typeof(Workflow)) {
        // first cast to object, then to return type to avoid compile error
        // compiler does not know mockedWorkFlows is Mock<DbSet<T>>, but you
        // know it already, because you checked type 'T'
        return (Mock<DbSet<T>>) (object) mockedWorkFlows; //cannot Workflow to T
    }
    // etc
    return null;
}
Run Code Online (Sandbox Code Playgroud)

是否好主意是一个不同的故事.


Dav*_*rno 6

switch通过打开不相关的值并使用var带有when防护的模式,可能会严重滥用C#7 来实现所需的功能:

public Mock<DbSet<T>> Mocked<T>() where T : class
{
    switch(true)
    {
        case var _ when typeof(T) == typeof(Workflow):
            return ...
        case var _ when typeof(T) == typeof(WorkflowError):
            return ...
        default:
            return null;
    }
}
Run Code Online (Sandbox Code Playgroud)

能够匹配switch语句中的类型是一个非常普遍的要求。在github上的官方语言仓库中有改进C#的建议(请参阅建议:开启System.Type和p 建议:通过通用约束进行模式匹配)。随着更多的模式匹配功能添加到C#中(当前设置为“ 7.X版本”),我们可能会获得更好的语法。