var array = new [] {d, "hello"} 隐式输入为 dynamic[] 而不是 string[] ?为什么?

var array = new [] {d, "hello"} is implicitly typed to dynamic[] and not string[] ? why?

dynamic d = 5;
var array = new[] {d,"hello"}

array 的隐式类型是什么?是dynamic[]而不是string[],为什么?

在深入了解 C# 时 - Jon Skeet 陈述了动态转换的规则:

An implicit conversion exists from any expression of type dynamic to almost any CLR type

后来他提到他故意说从 "expression of type dynamic" 转换,而不是从动态类型本身转换。

You may have also noticed that I wrote about a conversion “from an expression of type dynamic” to a CLR type, not a conversion from the dynamic type itself. This subtlety helps during type inference and other situations that need to consider implicit conversions between types

我有点困惑或者可能缺少一些非常基本的东西,但这解释了为什么 array 类型结果是 dynamic[] 而不是 string[]。谁能帮我理解他的意思。

在大多数情况下,您可以忽略此细节。但是,如果您仔细阅读规范,您会看到该语言考虑从类型 X 到类型 Y 的各种转换。语言在其他地方考虑从表达式 e 到类型 T 的转换,通常对确切的表达式有一些限制。

最简单的例子就是常量。没有从 intbyte 的隐式转换,但是 从 "a constant expression of type int and with a value within the range of byte" 到 byte 的隐式转换。

同样,没有从 dynamicstring 的转换(例如),但是 从 "an expression with a static type of dynamic" 到 [=22 的转换=].

这对于隐式类型数组之类的东西可能很重要。考虑这个表达式:

dynamic d = GetSomeDynamicValue(); // Compiler doesn't know or care actual value
var array = new[] { "hello", d };

array 的类型应该是什么?它最终是 dynamic[],而不是 string[] - 我 相信 是由于转换类型的不同。就是这样:

byte b = 10;
var array = new[] { b, 10 };

... 最终成为 int[],即使存在从常量表达式 10byte.

的隐式转换

底线:类型推断是规范中非常非常棘手的一点。有这两种不同类型的转换,值得了解它们,但大多数时候您不需要担心。