Switching on type with a generic return type

旧巷老猫 提交于 2020-02-14 17:25:47

问题


I'm working on making EF easier to unit test by writing some helpers that will make properties for me. I have a couple of backing fields

private Mock<DbSet<Workflow>> mockedWorkFlows;
private Mock<DbSet<WorkflowError>> mockedWorkFlowErrors;

And I want a generic function to be able to return me the correct backing field with the following function

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

There are several private backing fields which I want to be returned based on the type passed it.

However, even if I add a class constraint of Workflow, I get the same error.

I also tried switching on t's type but no luck there either. The types of the several backing fields do not share a common ancestor, other than object. Is what I'm trying to do possible?


回答1:


If I understand your intention correctly - you can do it like this:

// 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;
}

Whether it is good idea or not is a different story.




回答2:


It is possible to seriously abuse C#7's switch to achieve what you want by switching on an unrelated value and using the var pattern with when guards:

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;
    }
}

Being able to match on types in switch statements is a very common request. There are proposals for improvements to C# on the official language repo on github (see Proposal: switch on System.Type and pProposal: Pattern match via generic constraint). As and when more pattern matching functionality is added to C# (currently, set for "a 7.X release"), we may get nicer syntax for this functionality.



来源:https://stackoverflow.com/questions/46756172/switching-on-type-with-a-generic-return-type

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!