带有泛型参数的强制转换接口,由没有泛型参数的类实现

本文关键字:参数 泛型 实现 转换 接口 | 更新日期: 2023-09-27 18:02:00

我有两个接口,

public interface IDocument<SegType> where SegType : ISegment

public interface ISegment

基本上,我想强制实现IDocument的每个类都由一种类型的ISegment组成,并且使用这些类的人永远不需要知道他们的类内部使用哪种类型的ISegment

然后我创建了一个实现IDocument<SegType> where SegType : ISegment的类:

public class MyDocument : IDocument<MySegment>

和相应的MySegment:

public class FffSegment : ISegment

当我指定MyDocument作为类型时,所有这些都像我期望的那样编译和工作。为什么我不能隐式地将MyDocument的实例转换为IDocument<Isegment>类型?当我试着输入

IDocument<ISegment> doc = new MyDocument();

我得到错误

Cannot implicitly convert type 'MyDocument' to 'IDocument<ISegment>'. An explicit conversion exists (are you missing a cast?)

但是当我强制转换它时,它返回null。如果改成:

IDocument<MySegment> doc = new MyDocument();

可以工作,就像我将类定义更改为

时一样
public class MyDocument : IDocument<ISegment>

为什么我不能为iddocument的实现强制一个实现issegment的特定类型?我想为不同类型的IDocumentISegment重用此代码,也许有一天IDocument的一些实现将允许多种类型的ISegment,但MyDocument应该限制这种行为。我怎样才能强制执行这些要求,同时仍然编写足够通用的代码以便将来重用?

带有泛型参数的强制转换接口,由没有泛型参数的类实现

您需要了解相关和反向方差的复杂性:

public interface IDocument<out SegType> where SegType : ISegment
{}

我认为这应该使你的例子现在编译…

这里有一些阅读材料:

  • http://blogs.msdn.com/b/csharpfaq/archive/2010/02/16/covariance-and-contravariance-faq.aspx
  • http://msdn.microsoft.com/en-us/library/dd799517.aspx
  • http://en.wikipedia.org/wiki/Covariance_and_contravariance_ (computer_science)

因为IDocument<MySegment>不能直接转换为IDocument<ISegment>。如果可以,你可以这样做:

IDocument<ISegment> doc1 = new IDocument<MySegment>;
doc1.Add(new MyOtherSegment());   // invalid

(假设IDocument<T>Add(T newSegment)方法)

仔细看看你的设计,决定是否真的需要泛型,或者仅仅在IDocument中使用ISegment就足够了。