使用通用 return 类型打开类型
Switching on type with a generic return type
我正在努力通过编写一些可以为我创建属性的助手来使 EF 更容易进行单元测试。我有几个支持字段
private Mock<DbSet<Workflow>> mockedWorkFlows;
private Mock<DbSet<WorkflowError>> mockedWorkFlowErrors;
而且我希望通用函数能够 return 我使用以下函数
正确的支持字段
public Mock<DbSet<T>> Mocked<T>(T t) where T : class
{
if ( (object)t is Workflow)
{
return mockedWorkFlows; //cannot Workflow to T
}
}
有几个私有支持字段,我想根据传递给它的类型对其进行 returned。
然而,即使我添加 Workflow
的 class 约束,我也会得到同样的错误。
我也尝试打开 t's
类型,但也没有成功。除了对象之外,几个支持字段的类型不共享一个共同的祖先。我正在尝试做的事情可行吗?
如果我正确理解你的意图 - 你可以这样做:
// 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;
}
好不好是另一回事。
可以严重滥用 C#7 的 switch
来实现你想要的,方法是打开一个不相关的值并使用带有 when
守卫的 var
模式:
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;
}
}
能够匹配 switch
语句中的类型是一个非常常见的要求。 github 上的官方语言库中有改进 C# 的建议(参见 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"),我们可能会为此功能获得更好的语法。
我正在努力通过编写一些可以为我创建属性的助手来使 EF 更容易进行单元测试。我有几个支持字段
private Mock<DbSet<Workflow>> mockedWorkFlows;
private Mock<DbSet<WorkflowError>> mockedWorkFlowErrors;
而且我希望通用函数能够 return 我使用以下函数
正确的支持字段public Mock<DbSet<T>> Mocked<T>(T t) where T : class
{
if ( (object)t is Workflow)
{
return mockedWorkFlows; //cannot Workflow to T
}
}
有几个私有支持字段,我想根据传递给它的类型对其进行 returned。
然而,即使我添加 Workflow
的 class 约束,我也会得到同样的错误。
我也尝试打开 t's
类型,但也没有成功。除了对象之外,几个支持字段的类型不共享一个共同的祖先。我正在尝试做的事情可行吗?
如果我正确理解你的意图 - 你可以这样做:
// 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;
}
好不好是另一回事。
可以严重滥用 C#7 的 switch
来实现你想要的,方法是打开一个不相关的值并使用带有 when
守卫的 var
模式:
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;
}
}
能够匹配 switch
语句中的类型是一个非常常见的要求。 github 上的官方语言库中有改进 C# 的建议(参见 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"),我们可能会为此功能获得更好的语法。