new[]和new string[]有什么区别?

18

可能是重复问题:
这个 new[] 是什么缩写?


这两者有什么不同吗?

var strings = new string[] { "hello", "world" };

var strings2 = new[] { "hello", "world" };

13
我完全不同意这被认为是“过于局限”。虽然这不是一个高级问题,但绝对是相当多的人会遇到的事情。=) - J. Steen
6
我既不同意这个回答被贬值,也不认为它“过于局限”。这是一个合理的问题,许多初级(和肯定一些非初级)开发人员可能不知道。将其作为未来参考资料存在这里对很多人来说会非常有帮助。 - Dennis Traub
这是一个好问题,但已经被关闭为重复。我自己回答了一个类似的问题。链接 - Tim M.
1
我认为变体和重复不同,特别是当一个问题询问语法的含义,而另一个问题询问2个语法之间的区别时(语法?),但这只是一个小问题。反正已经有答案了。 - ajacian81
6个回答

29
在这种情况下,没有任何区别,因为new[]将推断提供的值的类型为string
请参见隐式类型数组

完全正确的C#在类型定义方面非常灵活,但我总是会隐式地定义变量类型以避免强制转换错误,或者直接查看在强制转换时可能出现的错误。 - Nickolaus
2
@Nickolaus:这里没有强制转换。该变量仍然是强类型的。 - Daniel Hilgarth
2
@Nickolaus,使用var关键字时也不需要进行任何转换,我猜这就是你想表达的。=) - J. Steen
是的,抱歉...我错过了var是动态类型...http://msdn.microsoft.com/zh-cn/library/ms173105.aspx - Nickolaus
1
@Nickolaus 不管是使用var还是显式声明类型,这只是口味和需要清晰度的程度的问题。^^ - J. Steen
2
@Nickolaus,当你提到var时,你不应该真的说它是动态的。与C#的dynamic不同,var实际上是强类型的。 - Caleb Jares

7
没有区别。 第二个是一种语法糖,称为"隐式类型数组",两个表达式都返回一个字符串数组。 当您不指定数组的类型时,它会从用于初始化数组的元素的类型中推断出来。 为了允许推断,表达式必须满足以下条件: 考虑像这样的隐式类型数组表达式:
   var arr = new []{ obj1, ... , objn }

并且初始化中所有元素的类型集为:

   S = {T1, ..., Tn}

为了允许推断(即没有编译器错误),必须能够将所有类型{ T1,...,Tn }隐式转换为集合中的某个类型S

因此,例如,给定以下类:

class Base { }
class Derived1 : Base { }
class Derived2 : Base { }
class Derived3
{ 
    public static implicit operator Base(Derived3 m)
    { return null; }
}

这段代码编译通过:

var arr = new []{ new Derived1(), new Derived2(), new Derived3(), new Base()};

以下内容不包括:

var arr = new []{ new Derived1(), new Derived2(), new Derived3() };

由于在第一种情况下,所有3种类型都可以隐式转换为类型Base,而Base类型在集合S = { Derived1,Derived2,Derived3,Base }中,而在第二种情况下,所有类型不能转换为集合S = { Derived1,Derived2,Derived3 }中的一个类型


这个特性是在C# 3.0中引入的,与匿名类型一起使用,它使得后者的数组实例化更加容易。

例如,如果没有隐式类型数组,这将非常难以获得:

var arrayOfAnonymous = new[] { new { A = 3, B = 4 }, new { A = 2, B = 5 } };

1
你知道是哪个版本的C#引入了这个吗? - Caleb Jares
1
它是在C# 3.0中引入的:http://msdn.microsoft.com/en-us/library/bb308966.aspx#csharp3.0overview_topic16 - xlecoustillier
@CalebJares:稍微详细解释了一下... - digEmAll

6
在这种情况下,没有区别。因为 helloworld 都是 string 类型的;
var strings2 = new[] { "hello", "world" };

创建一个与第一个相同的 string[] 数组。

enter image description here

第二个只是称为隐式类型数组

如果我们再往前走一步,它们有相同的IL代码。


我个人更喜欢使用LinqPad进行这种可视化操作。非常清晰易懂。=) - J. Steen
啊,没有调试模式 - 但是我只需将所有内容.Dump()到输出中,因为我需要它。=) - J. Steen
但是这个可视化需要调试模式 ;) - Soner Gönül
1
就我个人而言,我觉得linqpad中结果窗口的简洁输出(例如new[]{"hi","bye"}.Dump();)已经足够令人满意了。但是,品味总是非常主观的。=) - J. Steen
就像我说的,品味是主观的。很高兴能向你展示我的观点! - J. Steen
显示剩余2条评论

2

如果没有指定数组类型,编译器会将其解释为new string[] { "hello", "world" };

这就像使用var一样,编译器会处理你的意图。


1

new[] 创建一个 隐式类型数组,其中类型从元素中推断出来。而另一种方法则创建一个字符串数组。


是的,我表达不清楚了,它不是对象数组,而是从初始化的元素中推断类型。 - dutzu
那可是完全不同的事情。 - Daniel Hilgarth

0

没有区别。 在第二种情况下,C#编译器足够智能,可以推断出数组的类型,因为它看到用于初始化数组的值是字符串类型。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接