从 IEnumerable<int> 到 IEnumerable<dynamic> 的隐式转换

Implicit conversion from IEnumerable<int> to IEnumerable<dynamic>

到目前为止,我在 C# 中使用的 dynamic 不多,所以我在尝试创建一个简单的 WebGrid 类组件以供学习时遇到了一个(小)问题。

正常的 WebGridIEnumerable<dynamic> 作为其数据源,所以我模拟了它。然后我创建了一个如下所示的视图:

@model IEnumerable<int>

@{
  MyWebGrid grid = new MyWebGrid(Model);
}

在 MVC 项目中,这会导致运行时转换错误,因此我创建了一个小型控制台应用程序(这当然不会编译):

class Program
{
  class Foo { public int Id { get; } }

  static void Main()
  {
    CheckConversion(new List<int>().AsEnumerable()); // Error

    CheckConversion(new List<Foo>()); // works

    int x = 5;
    CheckSingleParameterConversion(x); // works
  }

  private static void CheckConversion(IEnumerable<dynamic> source) { }
  private static void CheckSingleParameterConversion(dynamic val) { }
}

错误(简而言之):无法从 IEnumerable<int> 转换为 IEnumerable<dynamic>

这些不同行为背后的确切原因是什么?我知道 dynamic 是一个引用类型,因此可以理解为什么 IEnumerable<int> 这里可能存在一些问题,但为什么它在单参数情况下工作呢?

问题不在 dynamic 本身,而在于 variance

MSDN

所述

Variance applies only to reference types; if you specify a value type for a variant type parameter, that type parameter is invariant for the resulting constructed type.

所以IEnumerable<int>不能转换为IEnumerable<dynamic>,因为int是一个值类型,而dynamic只是一个标有特殊属性的object