将通用<Derived>转换为通用<Base>
Cast Generic<Derived> to Generic<Base>
我有一个基本的 WPF UserControl,它处理派生 UserControl 的一些常见功能。在任何派生的 UserControl 的代码隐藏中,我调用一个事件
private void SomeClick(object sender, RoutedEventArgs e) {
HandleClick(sender);
MyDataGrid.Items.Refresh();
}
在我的基本 UserControl 中我这样做
public class BaseUserControl : UserControl {
protected void HandleClick(object sender) {
var vm = (BaseViewModel<Part>)DataContext;
...
}
}
这会抛出一个 InvalidCastException 因为 DataContext
是类型 BaseViewModel
但派生类型如 BaseViewModel<Wire>
或 BaseViewModel<Connector>
.
我该如何投射它?
您不能将 Generic<Derived>
转换为 Generic<Base>
。
想象一下,如果可以的话。您有一个 List<Wolf>
并将其转换为 List<Animal>
。现在你可以 .Add()
一个 Sheep
到你的 List<Animal>
。但是等等...现在您的 List<Wolf>
包含一个 Sheep
。真是一团糟
只有当您可以确保您投射到的对象在所有可能的形式下都是只读的时,这才会奏效。这就是 co- and contravariance 的全部内容。不过它只适用于接口。
我有一个基本的 WPF UserControl,它处理派生 UserControl 的一些常见功能。在任何派生的 UserControl 的代码隐藏中,我调用一个事件
private void SomeClick(object sender, RoutedEventArgs e) {
HandleClick(sender);
MyDataGrid.Items.Refresh();
}
在我的基本 UserControl 中我这样做
public class BaseUserControl : UserControl {
protected void HandleClick(object sender) {
var vm = (BaseViewModel<Part>)DataContext;
...
}
}
这会抛出一个 InvalidCastException 因为 DataContext
是类型 BaseViewModel
但派生类型如 BaseViewModel<Wire>
或 BaseViewModel<Connector>
.
我该如何投射它?
您不能将 Generic<Derived>
转换为 Generic<Base>
。
想象一下,如果可以的话。您有一个 List<Wolf>
并将其转换为 List<Animal>
。现在你可以 .Add()
一个 Sheep
到你的 List<Animal>
。但是等等...现在您的 List<Wolf>
包含一个 Sheep
。真是一团糟
只有当您可以确保您投射到的对象在所有可能的形式下都是只读的时,这才会奏效。这就是 co- and contravariance 的全部内容。不过它只适用于接口。