- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
具有类型参数的继承泛型类的协变是子类
我想构建一个 MVVM 项目。我需要构建一个集合来包含一些 ViewModel。
这些 ViewModel 是通用类。和一些模型是相似的。例如三角形和矩形的形状...
我想将它们收集到一个集合中。所以集合使用基类类型。
问题是这些继承的 ViewModel 不会被识别为子类的。
这是一个场景:
namespace WpfApp1
{
public interface I { } //interface
public class M : I { } //Model base
public class MA : M { } //Modle A
public class MB : M { } //Modle B
public class VM<T> where T : class, I { } //ViewModel Base
public class VMS<T> : VM<T> where T : class, I { }//ViewModel Base
public class VMA : VMS<MA> { } //ViewModel A
public class VMB : VMS<MB> { } //ViewModel B
public class Problem
{
List<VMS<I>> VMList = new List<VMS<I>>(); //
public void StupidThing() // F: fail O: Ok
{
VMList.Add(new VMB()); // F why?
VMS<I> a = new VMB(); //1 F why?
VMS<M> b = new VMB(); //2 F why?
VMS<MA> c = new VMB(); //3 F
VMS<MB> d = new VMB(); //4 O
VMA e = new VMB(); //5 F
VMB f = new VMB(); //6 O
}
}
}
在StupidThing函数中,我知道第3行和第5行是错误的,第4行和第6行没问题。但为什么第 1,2 行是错误的。
最佳答案
VMB 实现 VM
VMS 实现 VM,这意味着 VMS 应该包含具有相同 VM
GetModel/SetModel 方法有两种不同的签名和一些编译问题。因此,您不能简单地将 VMB 转换为 VM 并在您的集合 VMList 中使用它。
关于c# - 具有类型参数的继承泛型类的协变是子类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45860788/
在我的设置中,我试图有一个界面 Table继承自 Map (因为它主要用作 map 的包装器)。两个类继承自 Table - 本地和全局。全局的将有一个可变的映射,而本地的将有一个只有本地条目的映射。
Rust Nomicon 有 an entire section on variance除了关于 Box 的这一小节,我或多或少地理解了这一点和 Vec在 T 上(共同)变体. Box and Vec
我是一名优秀的程序员,十分优秀!