【问题标题】:Action<List<Something>> contravariance limitationAction<List<Something>> 逆变限制
【发布时间】:2013-12-12 18:17:15
【问题描述】:

我正在编写一个网络应用程序,其中对象由 id 请求并通过委托回调返回:

public static void requestById<ModelType>(T id, Action<ModelType> callback)
    where ModelType : AbstractModel<T>
{
}

为方便起见,我有一个方法可以一次请求多个对象:

public static void requestByIds<ModelType>
    (List<T> ids, Action<List<ModelType>> callback)
    where ModelType : AbstractModel<T>, new()
{
}

再往下,我有一个具有多个子对象的抽象模型对象,以及一个请求它的子对象的方法:

public abstract void requestSections(Action<List<AbstractSection>> callback);

然后是具体类中的实现:

public override void requestSections(Action<List<AbstractSection>> callback)
{
    Section.requestByIds<Section>(this.sectionIds, callback);
}

我突然找到了代表

Action<List<AbstractSection>>

不兼容

Action<List<Section>>

这是 C# 中逆变的限制吗?有什么解决方法可以让我的覆盖方法起作用吗?谢谢

【问题讨论】:

    标签: c# list action contravariance


    【解决方案1】:

    List 是不变的,它不是协变或逆变的。

    如果您使用IEnumerable&lt;T&gt; 而不是列表,那么您可以依赖IEnumerable&lt;T&gt;T 表示协变,这使得Action&lt;IEnumerable&lt;T&gt;&gt; 相对于T 逆变。

    【讨论】:

    • 我已将参数类型更改为使用Action&lt;IEnumberable&lt;T&gt;&gt;,但我仍然发现它抱怨Action&lt;List&lt;AbstractSection&gt;&gt;Action&lt;List&lt;Section&gt;&gt; 的协方差
    • @Vesuvian 当然可以,因为您不能将Action&lt;List&lt;AbstractSection&gt;&gt; 转换为Action&lt;List&lt;Section&gt;&gt;,恰恰是因为List 是不变的。但是,您可以将 Action&lt;IEnumerable&lt;AbstractSection&gt;&gt; 转换为 Action&lt;IEnumerable&lt;Section&gt;&gt;
    • 对不起,我打错了,我的意思是写:“Action&lt;IEnumberable&lt;AbstractSection&gt;&gt; and Action&lt;IEnumberable&lt;Section&gt;&gt;”。我相信这是因为我试图将抽象转换为具体而不是具体到抽象。
    • @Vesuvian 不,在这种情况下,Action&lt;IEnumerable&lt;T&gt;&gt; 相对于T 是逆变的,而不是协变的。这种转换应该可以正常工作;如果您遇到错误,您显然没有进行这种类型的转换。
    猜你喜欢
    • 1970-01-01
    • 2011-06-23
    • 2019-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多