关于c#:无法隐式“包装”IEnumerable


Unable to implicitly 'wrap' an IEnumerable

本问题已经有最佳答案,请猛点这里访问。

对于此类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Wrapper<T>
{
    public Wrapper(T value)
    {
        Value = value;
    }

    public T Value { get; }

    public static implicit operator Wrapper<T>(T value)
    {
        return new Wrapper<T>(value);
    }
}

此代码段无法编译:

1
2
IEnumerable<int> value = new [] { 1, 2, 3 };
Wrapper<IEnumerable<int>> wrapper = value;

error CS0266: Cannot implicitly convert type 'System.Collections.Generic.IEnumerable< int>' to 'Spikes.Implicit.Wrapper< System.Collections.Generic.IEnumerable< int>>'. An explicit conversion exists (are you missing a cast?)

但编译器对此非常满意:

1
Wrapper<IEnumerable<int>> wrapper = new [] { 1, 2, 3 };

为什么?


C语言规范清楚地说明了这一点:

第6.4.1节允许的用户定义转换

For a given source type S and target type T, if S or T are nullable
types, let S0 and T0 refer to their underlying types, otherwise S0 and
T0 are equal to S and T respectively. A class or struct is permitted
to declare a conversion from a source type S to a target type T only
if all of the following are true:

  • S0 and T0 are different types.
  • Either S0 or T0 is the class or struct type in which the operator declaration takes place.
  • Neither S0 nor T0 is an interface-type.
  • Excluding user-defined conversions, a conversion does not exist from S to T or from T to S.

你的案件违反了条件第3点。源类型是接口!