这是 C# 4 中的协方差错误吗? [英] Is this a covariance bug in C# 4?

查看:19
本文介绍了这是 C# 4 中的协方差错误吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下面的一段代码中,我希望能够从 elements 隐式转换为 baseElements 因为 TBase 可以隐式转换为 IBase.

In the following piece of code I expected to be able to implicitly cast from elements to baseElements because TBase is implicitly convertible to IBase.

public interface IBase { }
public interface IDerived : IBase { }
public class VarianceBug
{
    public void Foo<TBase>() where TBase : IBase
    {
        IEnumerable<TBase> elements = null;
        IEnumerable<IDerived> derivedElements = null;
        IEnumerable<IBase> baseElements;

        // works fine
        baseElements = derivedElements;

        // error CS0266: Cannot implicitly convert type 
        //   'System.Collections.Generic.IEnumerable<TBase>' to 
        //   'System.Collections.Generic.IEnumerable<IBase>'. 
        //   An explicit conversion exists (are you missing a cast?)
        baseElements = elements;
    }
}

但是,我收到了评论中提到的错误.

However, I get the error that is mentioned in the comment.

引用规范:

A 类型 T 可以方差转换为类型 T 如果 T> 是使用变体类型参数 T<X1, …, Xn> 声明的接口或委托类型,并且对于每个变体类型参数 Xi,以下条件之一成立:

A type T<A1, …, An> is variance-convertible to a type T<B1, …, Bn> if T is either an interface or a delegate type declared with the variant type parameters T<X1, …, Xn>, and for each variant type parameter Xi one of the following holds:

  • Xi 是协变的,并且存在从 AiBi

  • Xi is covariant and an implicit reference or identity conversion exists from Ai to Bi

Xi 是逆变的,并且存在从 BiAi

Xi is contravariant and an implicit reference or identity conversion exists from Bi to Ai

Xi 是不变的,存在从 AiBi

Xi is invariant and an identity conversion exists from Ai to Bi

检查我的代码,它似乎与规范一致:

Checking my code, it appears to be consistent with the spec:

  • IEnumerable 是一种接口类型

IEnumerable 是用变体类型参数声明的

IEnumerable<out T> is declared with variant type parameters

T 是协变的

存在从 TBaseIBase

那么 - 这是 C# 4 编译器中的错误吗?

So - is it a bug in the C# 4 compiler?

推荐答案

Variance 仅适用于引用类型(或存在 identity 转换).不知道TBase是引用类型,除非你加上:class:

Variance only works for reference-types (or there is an identity conversion). It is not known that TBase is reference type, unless you add : class:

 public void Foo<TBase>() where TBase : class, IBase

因为我可以写一个:

public struct Evil : IBase {}

这篇关于这是 C# 4 中的协方差错误吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆