- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个看起来像这样的接口(interface)结构:
最基本的级别是具有以下定义的 IDataProducer:
public interface IDataProducer<out T>
{
IEnumerable<T> GetRecords();
}
和一个如下所示的 IDataConsumer:
public interface IDataConsumer<out T>
{
IDataProducer<T> Producer { set; }
}
最后,我得到了一个从 IDataConsumer 派生的 IWriter,如下所示:
public interface IWriter<out T> : IDataConsumer<T>
{
String FileToWriteTo { set; }
void Start();
}
我想让 IWriter 的泛型类型 T 协变,这样我就可以实现一个工厂方法来创建可以处理不同对象的 Writers,而不必提前知道将返回什么类型。这是通过将通用类型标记为“out”来实现的。问题是,由于这个原因,我在 IDataConsumer 上遇到编译错误:
Invalid variance: The type parameter 'T' must be contravariantly valid on 'IDataConsumer<T>.Producer'. 'T' is covariant.
我不太确定这是怎么回事。在我看来,泛型类型在整个接口(interface)链中都被标记为协变的,但我很可能并不完全理解协变是如何工作的。有人可以向我解释我做错了什么吗?
最佳答案
问题是你的 Producer
属性是只写的。也就是说,你实际使用的是 T
以一种逆变方式,通过传递类型 T
上的通用值进入接口(interface)的实现者,而不是实现者将其传递出去。
我最喜欢 C# 语言设计团队处理泛型接口(interface)中的变体特性的方式之一是,用于表示协变和逆变类型参数的关键字与参数的使用方式是助记符。我总是很难记住“协变”和“逆变”这两个词的意思,但我从来没有遇到过记住什么的问题 out T
与 in T
方法。前者表示你 promise 只返回T
来自接口(interface)的值(例如方法返回值或属性 getter ),而后者意味着您 promise 只接受 T
接口(interface)中的值(例如方法参数或属性 setter )。
您为 Producer
提供了一个 setter,违背了这个 promise 。属性(property)。
根据这些接口(interface)的实现方式,您可能想要的是 interface IDataConsumer<in T>
反而。那至少会编译。 :) 而且只要IDataConsumer<T>
实现实际上只消耗了 T
值(value)观,那可能会奏效。没有更完整的例子很难说。
关于c# - 如何通过多个接口(interface)协变 "carry",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43905064/
COW 不是奶牛,是 Copy-On-Write 的缩写,这是一种是复制但也不完全是复制的技术。 一般来说复制就是创建出完全相同的两份,两份是独立的: 但是,有的时候复制这件事没多大必要
我是一名优秀的程序员,十分优秀!