不兼容的泛型类型
本文关键字:泛型类型 不兼容 | 更新日期: 2023-09-27 18:30:49
我不明白为什么我不能在另一个泛型的定义中使用特定的泛型类型。
所以我有这个:
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选项卡式工作区控制器,如下所示:
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>
我认为这篇文章是相关的:
约束不是签名的一部分
你的问题伤害了我的大脑,但我相信这就是正在发生的事情:
-
编译器并不"知道"
TTabbedWorkspaceView
是一个TabbedWorkspaceView
,因为这个信息只是通过一个不是签名一部分的约束给出的。 -
TTabbedWorkspaceView
通过TabbedWorkspaceController
的继承作为TMdiWorkspaceView
传递给MdiWorkspaceController
。 -
MdiWorkspaceController
的约束验证在TMdiWorkspaceView
失败,因为它被赋予为不"已知"为IMdiWorkspaceView
的东西。
解决方案:CA1005。
可以在另一个泛型类型的定义中使用泛型类型。这是一个简化的示例:
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的转换。因此,我认为在您的继承结构和参数中的某个地方,编译器没有路径或路径不匹配。我建议您删除参数并简化问题空间,直到找到源。
这段代码真的很复杂,我花了一段时间才解开它(我仍然不明白它应该是什么意思)。
我认为问题在于MdiWorkspaceController
要求其TMdiWorkspaceView
和TWorkItemViewFrame
直接相关,但你不能保证这一点。
要解决此问题,您可以将IMdiWorkspaceView
界面更改为:
public interface IMdiWorkspaceView<TWorkItemViewFrame, T2, T3>
自:
public interface IMdiWorkspaceView<in TWorkItemViewFrame, T2, T3>
in
基本上放宽了对TWorkItemViewFrame
的要求,这将使你的代码编译。
如果IMdiWorkspaceView
的定义是这样的,它不会用in
编译,这意味着你编写的代码不是类型安全的。