【问题标题】:Cannot convert type to instance of interface in generic method with type constraint?无法在具有类型约束的泛型方法中将类型转换为接口实例?
【发布时间】:2013-03-24 12:21:22
【问题描述】:

为什么这会给我一个编译时错误Cannot convert 'ListCompetitions' to 'TOperation'

public class ListCompetitions : IOperation
{
}

public TOperation GetOperation<TOperation>() where TOperation : IOperation
{
    return (TOperation)new ListCompetitions(); 
}

然而这是完全合法的:

public TOperation GetOperation<TOperation>() where TOperation : IOperation
{
    return (TOperation)(IOperation)new ListCompetitions(); 
}

【问题讨论】:

  • 长颈鹿是一种动物。格里是一只长颈鹿。在下一句中,“T”可以替换为任何一种动物。长颈鹿格里是个T。现在你看到问题了吗?使该句子成立的 T 的唯一有效值是“giraffe”和“animal”,但 T 可以是任何种动物。
  • 感谢 Eric,这是有道理的(尽管我认为它仍然可能是运行时错误,而不是编译器错误,尽管我确信你们以这种方式实现它有更深层次的原因这让我望而却步..)

标签: c# .net generics interface


【解决方案1】:

这种转换是不安全的,因为您可以为TOperation 提供不同于ListCompetitions 的通用参数,例如,您可以:

public class OtherOperation : IOperation { }
OtherOperation op = GetOperation<OtherOperation>();

如果编译器允许你的方法,这将在运行时失败。

你可以添加一个新的约束,例如

public TOperation GetOperation<TOperation>() where TOperation : IOperation, new()
{
    return new TOperation();
}

或者,您可以将返回类型更改为IOperation

public IOperation GetOperation()
{
    return new ListCompetitions();
}

从您的示例中不清楚在这种情况下使用泛型有什么好处。

【讨论】:

  • 您正在投射到TOperation,而不是IOperation
  • @IlyaIvanov - 他选择TOperation 而不是IOperation
  • 是的,没有立即发现IT 的区别,+1
  • 忽略用法,这是一个精简的例子。为什么不像其他演员那样允许运行时失败?为什么允许我这样做:` (TOperation)(IOperation)new ListCompetitions();` ?
  • @MalcomTucker 你可以“向上”投射,也可以“向下”投射,但不能直接“侧身”投射。
【解决方案2】:

因为TOperation 可能是实现IOperation任何东西,所以您不能确定ListCompetitionsTOperation

你可能想要返回一个 IOperation:

public IOperation GetOperation<TOperation>() where TOperation : IOperation
{
    return new ListCompetitions(); 
}

【讨论】:

  • 那么,泛型参数TOperation的目的是什么?
  • Svick - 在实际代码中,TOperation 将是 IOperation 的更具体版本,这将是一个返回正确具体的工厂方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多