从 IEnumerable<int> 到 IEnumerable<dynamic> 的隐式转换
Implicit conversion from IEnumerable<int> to IEnumerable<dynamic>
到目前为止,我在 C# 中使用的 dynamic
不多,所以我在尝试创建一个简单的 WebGrid
类组件以供学习时遇到了一个(小)问题。
正常的 WebGrid
将 IEnumerable<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
。
到目前为止,我在 C# 中使用的 dynamic
不多,所以我在尝试创建一个简单的 WebGrid
类组件以供学习时遇到了一个(小)问题。
正常的 WebGrid
将 IEnumerable<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
。