- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
这是 MVVM + WPF,但实际上与这些工具没有太大关系。问题比较笼统,属于OO设计。
昨天 MarcinJuraszek 帮助我提出了一个很好的解决方案来解决 original problem .该解决方案解决了手头的问题,但现在我陷入了下一个层次。事情是这样的:
查看模型
我的 ViewModel 类继承自一个通用的抽象父 ViewModel 类:
Public MustInherit Class ViewModelBase
Implements INotifyPropertyChanged, IDisposable
...
End Class
Class SalesOrderEntryViewModel
Inherits ViewModelBase
Implements IEditorViewModel, IChildViewModel
...
End Class
IEditorViewModel
和
IChildViewModel
是我的一些具体 ViewModel 实现的接口(interface)。
Interface IView(Of T As ViewModelBase)
WriteOnly Property MyVM As T
ReadOnly Property HeaderText As String
End Interface
SalesOrderEntryViewModel
的具体 View 我上面描述的定义为:
Class SalesOrderEntryPage
Implements IView(Of SalesOrderEntryViewModel)
End Class
Dim Views As List(Of IView(Of ViewModelBase))
SalesOrderEntryPage
的对象时类到这个列表,它会抛出一个运行时异常,告诉我它不能从
SalesOrderEntryPage
转换。至
IView(Of ViewModelBase)
,尽管查看定义,
SalesOrderEntryPage
真的是
IView(Of ViewModelBase)
.
最佳答案
您面临的问题与泛型的使用有关,并且与称为泛型类型参数变化的概念有关。泛型接口(interface)的类型参数可以是不变的、协变的或逆变的。
默认情况下,通用接口(interface)的类型 T 是不变的。这意味着,您可以将 T 用作方法参数的类型,也可以用作方法的返回类型。不利的一面是,这意味着以下任何一项都不可能:
Cast IView(Of ViewModelBase) to IView(Of SalesOrderEntryViewModel)
Cast IView(Of SalesOrderEntryViewModel) to IView(Of ViewModelBase)
IView(Of T)
有一个需要 的方法 类型的参数T
: 这意味着 IView(Of SalesOrderEntryViewModel)
有一个方法,它需要一个类型为 SalesOrderEntryViewModel
的参数.但如果你能投IView(Of SalesOrderEntryViewModel)
至IView(Of ViewModelBase)
, 你会期望它有一个参数类型为 ViewModelBase
的方法,但它没有,因为该方法是为 SalesOrderEntryViewModel
类型的参数设计的仅适用于其通用版本或其他源自 ViewModelBase
的 ViewModel .结果:您不能将 IView(Of SalesOrderEntryViewModel) 转换为 IView(Of ViewModelBase)。 IView(Of T)
有一个方法 返回 T 类型的值 并假设类上的方法实现了IView(Of ViewModelBase)
将返回 SalesOrderEntryViewModel
,这没关系,因为 SalesOrderEntryViewModel
是 ViewModelBase
的一个实例.到目前为止,一切都很好。但是,如果您现在尝试将此类转换为 IView(Of SomeOtherViewModel
,它不再起作用了,因为你的方法想要返回的类型 SalesOrderEntryViewModel
不是 SomeOtherViewModel
的实例.结果:您不能将 IView(Of ViewModelBase) 转换为 IView(Of SalesOrderEntryViewModel)。 T
中使您的界面逆变。 : 这意味着你不能使用 T 作为你的方法的返回类型,但你可以强制转换
Interface(Of Base)
至
Interface(Of Derived)
.
Interface IContravariant(Of In A)
Sub SetSomething(ByVal sampleArg As A)
Sub DoSomething(Of T As A)()
' The following statement generates a compiler error.
' Function GetSomething() As A
End Interface
T
中使你的接口(interface)协变。 : 那么你不能有接受
T
类型参数的方法, 但你可以投
Interface(Of Derived)
至
Interface(Of Base)
.
Interface ICovariant(Of Out R)
' The following statement generates a compiler error
' because you can use only contravariant or invariant types
' in generic contstraints.
' Sub DoSomething(Of T As R)()
End Interface
When I try to add an object of SalesOrderEntryPage class to this list, it throws a run-time exception telling me that it cannot convert from SalesOrderEntryPage to IView(Of ViewModelBase)
IView
ViewModelType 中的协变。因此,您失去了通过
IView
设置 ViewModel 的能力。界面。
readonly
填充您的收藏。您的 View 的版本。
关于vb.net - 为什么不能将 IView(Of SpecificViewModel) 转换为 IView(Of ViewModelBase)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15424349/
我是一名优秀的程序员,十分优秀!