问题
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