我有一个关于使用的问题new[]
。
想象一下:
Object.SomeProperty = new[] {"string1", "string2"};
SomeProperty 需要一个字符串数组。
我知道这个代码片段会起作用。但我想知道它在幕后做了什么。是否new[]
创建类的实例object
并在SomeProperty
其中自动将其转换为string
对象?
谢谢
我有一个关于使用的问题new[]
。
想象一下:
Object.SomeProperty = new[] {"string1", "string2"};
SomeProperty 需要一个字符串数组。
我知道这个代码片段会起作用。但我想知道它在幕后做了什么。是否new[]
创建类的实例object
并在SomeProperty
其中自动将其转换为string
对象?
谢谢
好吧,这里还是有点混乱。
正在进行的推断与 Object.SomeProperty 的类型无关,而是与数组初始值设定项中表达式的类型有关。换句话说,你可以这样做:
object o = new[] { "string1", "string2" };
并且 o 仍然是对字符串数组的引用。
基本上,编译器会查看如下表达式:
new[] { A, B, C, D, ... }
(其中 A、B、C、D 等是表达式)并尝试找出要使用的正确数组类型。它仅将 A、B、C 和 D 等类型视为数组元素类型。采用这组候选类型,它试图找到一个所有其他类型都可以隐式转换为的类型。如果不完全是一种这样的类型,那么编译器会抱怨。
例如:
new[] { new Form(), new MemoryStream() }
不会编译 - 既不能MemoryStream
也不能Form
转换为另一个。然而:
new[] { GetSomeIDisposable(), new MemoryStream() }
将被视为 ,因为存在从toIDisposable[]
的隐式转换。同样地:MemoryStream
IDisposable
new[] { 0, 1, 3.5 } // double[]
new[] { 1, 3, 100L } // long[]
这只是语法糖。编译器将在此处推断实际需要的类型并创建等效于显式构造的代码:
Object.SomeProperty = new string[] {"string1", "string2"};
没有new[]
在运行时执行的事情。
大致翻译为:
string[] $temp = new string[2];
$temp[0] = "string1";
$temp[1] = "string2";
Object.SomeProperty = $temp;
有趣的是,var x = new[] { "string1", "string2" };
同样有效,它可以推断 x 为 a string[]
,但var x = { "string1", "string2" };
失败了。
编译器替换:
Object.SomeProperty = new[] {"string1", "string2"};
和:
Object.SomeProperty = new string[] {"string1", "string2"};
我希望从您的回复中您不会在这里对类型替换和类型推断感到困惑!我假设 Object.SomeProperty 的类型是 string[],尽管由于数组协方差,它可能是 object[](注意这不是一件好事 - 查看Eric Lippert关于这个主题的帖子!)。
编译器使用启发式执行类型推断 - 它确定“string1”和“string2”是字符串类型,因此它有效地将您的代码替换为:-
Object.SomeProperty = new string[] {"string1", "string2"};
它真的是那么简单!这一切都是在编译时完成的,在运行时什么都没有。