Tag: 协方差

协方差和反演 – 只是调用保证基类行为的不同机制?

我正在努力理解这两个概念。 但我想在经过许多video和SO QA之后,我将其简化为最简单的forms: 协变 – 假设一个子类型可以做它的基类型。 逆变 – 假设您可以像对待基类型一样处理子类型。 假设这三个类: class Animal { void Live(Animal animal) { //born! } void Die(Animal animal) { //dead! } } class Cat : Animal { } class Dog : Animal { } 协变 任何动物都可以做动物做的事。 假设子类型可以执行其基类型的操作。 Animal anAnimal = new Cat(); anAnimal.Live(); anAnimal.Die(); Animal anotherAnimal = new Dog(); anotherAnimal.Live(); anotherAnimal.Die(); […]

C#转换inheritance的通用接口

我遇到了一些麻烦,让我开始构建一个我想出的界面。 这是C#Windows Forms的MVP设计。 我有一个IView类,我在我的表单类上实现。 还有一个IPresenter,我将其导入各种特定的演示者。 每个Presenter将根据角色以不同方式管理IView,例如打开对话框以使用AddPresenter输入新数据集,而不是使用EditPresenter编辑现有数据,EditPresenter会将数据预加载到表单上。 每个都inheritance自IPresenter。 我想这样使用代码: AddPresenter pres = new AddPresenter(); 我基本上有这个工作,但这些演示者和他们管理的视图被捆绑到运行时加载的插件,这意味着我需要一个作为插件接口的Manager类采用“模式”参数。 此模式参数用于工厂方法来创建“添加”或“编辑演示者”,但由于稍后会调用显示对话框,因此我需要通过IPresenter接口进行调用,如下所示: private IPresenter pres; public ShowTheForm() { pres.ShowDialog(); } 现在,我遇到的问题是将AddPresenter的具体实例表示为’pres’成员。 这是我所拥有的简化版本: interface IView { void ViewBlah(); } interface IPresenter where V : IView { void PresBlah(); } class CView : IView { public void ViewBlah() { } } class CPresenter : […]

协方差如何比多态更冷……而不是多余的?

.NET 4引入了协方差。 我想这很有用。 毕竟,MS经历了将其添加到C#语言的所有麻烦。 但是,为什么协方差比良好的旧多态更有用呢? 我写这个例子来理解为什么我应该实现Covariance,但我仍然没有得到它。 请赐教。 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Sample { class Demo { public delegate void ContraAction(T a); public interface IContainer { T GetItem(); void Do(ContraAction action); } public class Container : IContainer { private T item; public Container(T item) { this.item = item; } public T […]

与C#的协方差

我在c#代码中遇到了一些有趣的协方差问题。 我有一个通用的Matrix类,它已被实例化,例如Matrix , Matrix和Matrix 。 对于我的业务逻辑,我将它们Wrapper成通用的Wrapper 。 此Wrapper实现非通用的INonGenericWrapper接口。 所以,我有Wrapper , Wrapper和Wrapper 。 我的问题是:我想为所有这3个Wrapper定义一个容器。 我不能说List<Wrapper> ,因为我无法将Wrapper插入此集合中。 我甚至不能说List ,因为在我的foreach中,我想访问genericsMatrix参数。 俗气的部分:这个Wrappers将使用明确的类型(de-)序列化: MySerializer<Wrapper>.Serialize(_myInstanceOfWrappedApple) 。 我认为很明显我想在序列化时避免大量的typeof开关.. 我可能的解决方法是什么? 我有点卡住了。 提前致谢,

C#generics类中的协方差

C#4.0 .NET 4.5 Silverlight 5我似乎无法找到解决方案,所以需要一些帮助。 我有基类Base和派生类Child:Base。 我还有一个helper类,它具有generics类型来执行特定的工作,一个EF实体Helper,其中T:EntityObject。 Child使用特定实体MyEntity:EntityObject执行特定工作。 所以我尝试过: public class Base { protected Helper helper; } public class Child : Base { public Child() { helper = new Helper(); } } 我希望更多派生类必须知道更具体的generics参数,我认为这是什么协方差……但是这不起作用…… 这样设计课程的“正确”方法是什么? 编辑:抱歉,我没有100%清楚为什么我无法实现我的需要。 一个。 使用通用Base的解决方案不起作用,因为Base的用户不知道T类型。 想像: public class User { private Base base; // this will not compile. public User(TypeEnum t) { if(t […]

无法将MyType 隐式转换为MyType

我不确定这是否是Covariance和Contravariance问题,但我不能让这个工作。 这是代码: public interface IDto { } public class PaginatedDto where TDto : IDto { public int PageIndex { get; set; } public int PageSize { get; set; } public int TotalCount { get; set; } public int TotalPageCount { get; set; } public bool HasNextPage { get; set; } public bool HasPreviousPage { get; […]

C#类型转换错误,尽管通用约束

为什么,对于类P的类型参数T的“必须从Ainheritance”的通用约束,第一次调用成功但第二次调用失败并且注释中详细说明了类型转换错误: abstract class A { } static class S { public static void DoFirst(A argument) { } public static void DoSecond(ICollection argument) { } } static class P where T : A, new() { static void Do() { S.DoFirst(new T()); // this call is OK S.DoSecond(new List()); // this call won’t compile with: /* cannot […]

与C#数组的协方差和逆差

在阅读维基百科关于协方差和逆变的文章的一部分时,我遇到了以下粗体句: 首先考虑数组类型构造函数:从类型Animal我们可以创建类型Animal[] (“动物数组”)。 我们应该把它视为 协变: Cat[]是Animal[] 逆变: Animal[]是Cat[] 或两者(不变)? 如果我们希望避免类型错误,并且数组支持读取和写入元素,那么只有第三种选择是安全的。 显然,并非每个Animal[]都可以被视为Cat[] ,因为从数组中读取的客户端将期望Cat,但Animal[]可能包含例如Dog 。 所以逆变规则并不安全。 相反, Cat[]不能被视为Animal[] 。 应该总是可以将Dog放入Animal[] 。 对于协变数组,这不能保证是安全的,因为后备存储实际上可能是一组猫。 所以协变规则也不安全 – 数组构造函数应该是不变的。 请注意,这只是可变数组的一个问题; 协变规则对于不可变(只读)数组是安全的。 我理解这个概念; 我只是想要一个如何在C#中“无法保证安全”的例子 。

为什么C#数组是协变的,它带来了什么好处?

我无法理解为什么C#中的数组是协变的,以及这种协方差带来的好处。 考虑以下简单的代码示例: object[] myArray = new string[1]; myArray[0] = 1; 这段代码可以正常编译,但是会毫不客气地在运行时爆炸。 如果我尝试使用generics尝试同样的事情,编译器会抱怨我,我会在早期意识到我的愚蠢,所以我的问题是:为什么C#编译器允许这种与数组的协方差,而且,什么是潜在的好处?

派生类型的通用基类

我有以下代码。 class Header where T: IItem { } class HeaderA : Header { } class HeaderB : Header { } interface IItem { } class ItemA : IItem { } class ItemB : IItem { } Header h = new HeaderA(); 最后一行无法编译。 Cannot implicitly convert type ‘UserQuery.HeaderA’ to ‘UserQuery.Header’ HeaderA是Header的子类型,ItemA是IItem的子类型。 为什么它不起作用?