【问题标题】:C# .NET 4.0 generic covariance problem with cast exception带有强制转换异常的 C# .NET 4.0 通用协方差问题
【发布时间】:2011-04-08 04:59:40
【问题描述】:

我已经为此奋斗了一段时间,因此将不胜感激。这是我在 C# .NET 4.0 上遇到的情况。

public interface ITableBusinessLogicLayerIn<in TTableRecord> : IBusinessLogicLayer
    where TTableRecord : ITableRecord
{
// No definition
}

public interface ITableBusinessLogicLayerOut<out TTableRecord> : IBusinessLogicLayer
    where TTableRecord : ITableRecord
{
// No definition
}

我有一个实现这两个接口的对象。代码编译得很好。但在运行时,我可以按如下方式转换此对象:

(ITableBusinessLogicLayerOut<ITableRecord>)obj

但不是这样:

(ITableBusinessLogicLayerIn<ITableRecord>)obj

这非常令人困惑,我不确定我做错了什么。有人请指出我正确的方向。谢谢!

【问题讨论】:

  • 我确信这与“in”泛型参数主要用于 lambda 和方法而不是类的事实有关,因为它们都是关于传递一个值“in” .这就是我所拥有的。 :)

标签: .net generics c#-4.0 covariance contravariance


【解决方案1】:

逆变 (in) 允许您将具有不太具体类型的类型参数的对象强制转换为更具体的类型之一。例如,您不能将对象传递给需要字符串的类型,因此不能将需要字符串的类型强制转换为需要对象的类型。更多信息请看这里:http://msdn.microsoft.com/en-us/library/ee207183%28d=lightweight%29.aspx

举个例子:

class MyTableRecord : ITableRecord { }
ITableBusinessLogicLayerIn<ITableRecord> inA;
ITableBusinessLogicLayerIn<MyTableRecord> inB;
ITableBusinessLogicLayerOut<ITableRecord> outA;
ITableBusinessLogicLayerOut<MyTableRecord> outB;

您可以将inB 分配给inA,但不能反过来。您可以将outA 分配给outB,但不能反过来。

【讨论】:

  • 嗨,塔尔乔。我需要使用通用接口 ITableBusinessLogicLayerIn,以便我可以添加、更新任何类型的 ITableRecord 对象,即 UserRecord、RoleRecord、MenuRecord 等。我将如何实现这一点?
  • 对于您正在做的事情,您可能不需要差异。一个简单的泛型将起作用。仅当您希望能够将一种类型用于另一种类型时,它们都是相同的通用基础但具有不同的类型参数(例如在某些需要 IEnumerable 的地方使用 IEnumerable)时,才会出现差异。你通常必须选择一个方向或另一个,你不能同时做这两个(或者你基本上以不变性告终)。
  • 感谢您的回答和建议。非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多