1

我不明白为什么我不能在另一个定义中使用特定的泛型类型。

所以我有这个:

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

作为更具体的实现 TabbedWorkspaceController 中的 TTabbedWorkspaceView,如下所示:

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>

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

更新:

好的,感谢大家的帮助,我已经解决了这个问题,我需要让泛型类型流向 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>
4

3 回答 3

1

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

约束不是签名的一部分

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

  • 编译器不“知道”那TTabbedWorkspaceView是 a TabbedWorkspaceView,因为此信息仅通过不属于签名一部分的约束给出。

  • TTabbedWorkspaceView通过's 继承传递给MdiWorkspaceControlleras 。TMdiWorkspaceViewTabbedWorkspaceController

  • MdiWorkspaceController的约束验证失败TMdiWorkspaceView,因为它是作为不“已知”的东西给出的IMdiWorkspaceView

解决方案:CA1005

于 2013-09-11T01:50:19.440 回答
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 的转换。所以,我认为在你的继承结构和参数的某个地方,编译器没有路径或路径不匹配。我建议您删除参数并简化问题空间,直到找到源。

于 2013-09-11T02:35:53.517 回答
1

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

认为问题在于它MdiWorkspaceController需要它TMdiWorkspaceView并且TWorkItemViewFrame直接相关,但你不能保证这一点。

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

public interface IMdiWorkspaceView<TWorkItemViewFrame, T2, T3>

至:

public interface IMdiWorkspaceView<in TWorkItemViewFrame, T2, T3>

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

如果 的定义IMdiWorkspaceView不能与 一起编译in,则意味着您编写的代码不是类型安全的。

于 2013-09-11T02:47:17.867 回答