不兼容的泛型类型

时间:2013-09-11 01:16:30

标签: c# generics

我无法理解为什么我不能在另一个的定义中使用特定的泛型类型。

所以我有这个:

public abstract class MdiWorkspaceController<TWorkItemController, TMdiWorkspaceView, TWorkItemViewFrame, TWorkItemMainView> 
    : ViewableWorkspaceController<TWorkItemController>
    where TMdiWorkspaceView : class, IMdiWorkspaceView<TWorkItemViewFrame, TWorkItemMainView, TWorkItemMainView>
    where TWorkItemViewFrame : class, IWorkItemViewFrame<TWorkItemMainView>
    where TWorkItemMainView : class, IWorkItemMainView
    where TWorkItemController : ViewableWorkItemController{}

我试图使用

  public partial class TabbedWorkspaceView<TWorkItemMainView>
        : KryptonNavigator,
        IMdiWorkspaceView<TabbedWorkItemViewFrame<TWorkItemMainView>, TWorkItemMainView, TWorkItemMainView>
        where TWorkItemMainView : AbstractWorkItemView

作为TTabbedWorkspaceView在更具体的实现TabbedWorkspaceController中如下:

public class TabbedWorkspaceController<TWorkItemController, TTabbedWorkspaceView, TTabbedWorkItemViewFrame, TWorkItemMainView>
    : MdiWorkspaceController<TWorkItemController, TTabbedWorkspaceView, TTabbedWorkItemViewFrame, TWorkItemMainView>
    where TWorkItemController : ViewableWorkItemController
    where TTabbedWorkspaceView : TabbedWorkspaceView<TWorkItemMainView>
    where TTabbedWorkItemViewFrame : TabbedWorkItemViewFrame<TWorkItemMainView>
    where TWorkItemMainView : AbstractWorkItemView

但我得到一个错误,说TTabbedWorkspaceView必须可以转换为

IMdiWorkspaceView<TTabbedWorkItemViewFrame<TWorkItemMainView>, TWorkItemMainView, TWorkItemMainView>

以便在泛型类

中将其用作参数TMdiWorkspaceView
 MdiWorkspaceController<TWorkItemController, TTabbedWorkspaceView, TTabbedWorkItemViewFrame, TWorkItemMainView>

现在我很高兴地承认我处于“聪明”代码的个人界限,但在此之后,所有内容在应用程序级别变得完全具体和简化,所以我想继续使用我的设计。 / p>

更新

好的,感谢大家的帮助,我已经解决了这个问题,我需要让泛型类型流到TabbedWorkspaceView,而不是我声明了它。所以新版本是:

 public partial class TabbedWorkspaceView<TTabbedWorkItemViewFrame, TWorkItemMainView>
        : KryptonNavigator,
        IMdiWorkspaceView<TTabbedWorkItemViewFrame, TWorkItemMainView, TWorkItemMainView>
        where TTabbedWorkItemViewFrame : TabbedWorkItemViewFrame<TWorkItemMainView>
        where TWorkItemMainView : AbstractWorkItemView

然后:

 public class TabbedWorkspaceController<TWorkItemController, TTabbedWorkspaceView, TTabbedWorkItemViewFrame, TWorkItemMainView>
        : MdiWorkspaceController<TWorkItemController, TTabbedWorkspaceView, TTabbedWorkItemViewFrame, TWorkItemMainView>
        where TWorkItemController : ViewableWorkItemController
        where TTabbedWorkspaceView : TabbedWorkspaceView<TTabbedWorkItemViewFrame, TWorkItemMainView>
        where TTabbedWorkItemViewFrame : TabbedWorkItemViewFrame<TWorkItemMainView>
        where TWorkItemMainView : AbstractWorkItemView

然后在应用程序级别我可以:

public class TappWorkspaceController
    : TabbedWorkspaceController<TappWorkItemController, TappWorkspaceView, TappWorkItemViewFrame, TappWorkItemView>

3 个答案:

答案 0 :(得分:1)

我认为这篇文章是相关的:

Constraints are not part of the signature

你的问题伤害了我的大脑,但我相信这就是正在发生的事情:

  • 编译器“不知道”TTabbedWorkspaceViewTabbedWorkspaceView,因为此信息仅通过不属于签名的约束来提供。

  • TTabbedWorkspaceView通过MdiWorkspaceController的继承传递给TMdiWorkspaceView TabbedWorkspaceController

  • MdiWorkspaceControllerTMdiWorkspaceView的约束验证失败,因为它是以“{1}}未知”的方式提供的。

解决方案:CA1005

答案 1 :(得分:1)

您可以在另一个的定义中使用泛型类型。这是一个简化的例子:

class Program
{  
    public interface IBadFoo
    {
        void DoSomethingUnusual();
    }

    public interface IFoo
    { 
        void DoSomething();
    }

    public class Foo : IFoo
    {
        public void DoSomething()
        {           
        }
    }

    public abstract class SomeGenericBase<IFooClass>
        where IFooClass : IFoo
        //where IFooClass : IBadFoo
    {
        public abstract void DoSomethingElse();
    }

    public class SomeGeneric<FooClass> : SomeGenericBase<FooClass>
        where FooClass : Foo, new()
    {
        public override void DoSomethingElse()
       {
           FooClass fc = new FooClass();
           fc.DoSomething();
       }
   }

   public static void Main()
   {
       SomeGeneric<Foo> someGen = new SomeGeneric<Foo>();
       someGen.DoSomethingElse();
   }
}

请注意,如果我评论where IFooClass : IFoo并取消注释//where IFooClass : IBadFoo,那么我会收到类似的错误,因为没有从Foo转换为IBadFoo。所以,我认为在继承结构和参数中的某处,编译器没有路径或路径不匹配。我建议您删除参数并简化问题空间,直到找到源。

答案 2 :(得分:1)

这段代码非常复杂,我花了一段时间来解开它(我仍然不明白它应该是什么意思)。

认为问题在于MdiWorkspaceController要求其TMdiWorkspaceViewTWorkItemViewFrame直接相关,但您不能保证这一点。

要解决此问题,您可以更改IMdiWorkspaceView界面,例如:

public interface IMdiWorkspaceView<TWorkItemViewFrame, T2, T3>

为:

public interface IMdiWorkspaceView<in TWorkItemViewFrame, T2, T3>

in基本上放宽了对TWorkItemViewFrame的要求,这将使您的代码编译。

如果IMdiWorkspaceView的定义不能使用in进行编译,则表示您编写的代码不是类型安全的。