gpt4 book ai didi

c# - 如何通过多个接口(interface)协变 "carry"

转载 作者:行者123 更新时间:2023-11-30 13:18:49 28 4
gpt4 key购买 nike

我有一个看起来像这样的接口(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 Tin 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/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com