English 中文(简体)
C# 使用 new[]
原标题:
  • 时间:2008-11-28 08:19:17
  •  标签:

我有一个关于使用new[]的问题。

想象一下:

Object.SomeProperty = new[] {"string1", "string2"};

一些属性 (SomeProperty) 需要一个字符串数组。

我知道这段代码片段会运转。但我想知道它在内部都做了些什么。new[]会产生一个object类的实例,然后在SomeProperty中会自动将其转换为string对象吗?

谢谢 (Xièxiè)

最佳回答

好的,这里仍然有一点点混淆。

正在进行的推断与对象类型的某些属性无关,而是与数组初始化器中表达式的类型有关。换句话说,您可以这样做:

object o = new[] { "string1", "string2" };

而o仍然将是一个关于字符串数组的参考。

基本上,编译器会看到这样的表达式:

new[] { A, B, C, D, ... }

(其中A,B,C,D等均为表达式)并尝试找出正确的数组类型来使用。它仅考虑A、B、C和D(等)的类型作为数组元素类型。在选择候选类型集合后,它会尝试找到一个所有其他类型都可以隐式转换为的类型。如果没有 仅有一个 这样的类型,编译器将发出警告。

那么例如:

new[] { new Form(), new MemoryStream() }

不会编译 - MemoryStreamForm 两者都无法转换为另一个。 然而:

new[] { GetSomeIDisposable(), new MemoryStream() }

将被视为IDisposable[],因为存在从MemoryStreamIDisposable的隐式转换。同样:

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 是一个 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"};

那真的很简单!这一切都在编译时完成,没有一点运行时的操作。





相关问题
热门标签