6

我见过人们使用几种不同的方式来初始化数组:

string[] Meal = new string[]{"Roast beef", "Salami", "Turkey", "Ham", "Pastrami"};

或者另一种方式,也称为初始化是:

string[] Meats = {"Roast beef", "Salami", "Turkey", "Ham", "Pastrami" };

最好的方法是什么,两种方法之间的主要区别是什么(包括内存分配)?

4

4 回答 4

16

两种情况没有区别。编译器生成相同的字节码(newarrOpCode):

public static void Main()
{
   string[] Meal = new string[] { "Roast beef", "Salami", "Turkey", "Ham", "Pastrami"};
   string[] Meats = { "Roast beef", "Salami", "Turkey", "Ham", "Pastrami" };
}

MSIL:

.entrypoint
  // Code size       100 (0x64)
  .maxstack  3
  .locals init ([0] string[] Meal,
           [1] string[] Meats,
           [2] string[] CS$0$0000)
  IL_0000:  nop
  IL_0001:  ldc.i4.5
  IL_0002:  newarr     [mscorlib]System.String
  IL_0007:  stloc.2
  IL_0008:  ldloc.2
  IL_0009:  ldc.i4.0
  IL_000a:  ldstr      "Roast beef"
  IL_000f:  stelem.ref
  IL_0010:  ldloc.2
  IL_0011:  ldc.i4.1
  IL_0012:  ldstr      "Salami"
  IL_0017:  stelem.ref
  IL_0018:  ldloc.2
  IL_0019:  ldc.i4.2
  IL_001a:  ldstr      "Turkey"
  IL_001f:  stelem.ref
  IL_0020:  ldloc.2
  IL_0021:  ldc.i4.3
  IL_0022:  ldstr      "Ham"
  IL_0027:  stelem.ref
  IL_0028:  ldloc.2
  IL_0029:  ldc.i4.4
  IL_002a:  ldstr      "Pastrami"
  IL_002f:  stelem.ref
  IL_0030:  ldloc.2
  IL_0031:  stloc.0
  IL_0032:  ldc.i4.5
  IL_0033:  newarr     [mscorlib]System.String
  IL_0038:  stloc.2
  IL_0039:  ldloc.2
  IL_003a:  ldc.i4.0
  IL_003b:  ldstr      "Roast beef"
  IL_0040:  stelem.ref
  IL_0041:  ldloc.2
  IL_0042:  ldc.i4.1
  IL_0043:  ldstr      "Salami"
  IL_0048:  stelem.ref
  IL_0049:  ldloc.2
  IL_004a:  ldc.i4.2
  IL_004b:  ldstr      "Turkey"
  IL_0050:  stelem.ref
  IL_0051:  ldloc.2
  IL_0052:  ldc.i4.3
  IL_0053:  ldstr      "Ham"
  IL_0058:  stelem.ref
  IL_0059:  ldloc.2
  IL_005a:  ldc.i4.4
  IL_005b:  ldstr      "Pastrami"
  IL_0060:  stelem.ref
  IL_0061:  ldloc.2
  IL_0062:  stloc.1
  IL_0063:  ret
于 2013-04-19T14:18:19.597 回答
4

两者是相同的,并且会产生相同的 IL 代码。第二个只是第一个的语法糖。

于 2013-04-19T14:18:43.957 回答
3

这两种方式在编译后的代码中是等价的,选择你认为最清晰或者最容易阅读的方式。

于 2013-04-19T14:19:14.647 回答
2

请参阅Eric Lippert 对类似问题的回答。在这个特定场景中,它们都产生相同的编译代码和相同的结果。两种语法之间的唯一区别是第二种语法只能用于变量声明,这意味着您不能使用它来更改现有变量的值。例如:

// Compiles fine
string[] Meats = {"Roast beef", "Salami", "Turkey", "Ham", "Pastrami" };

// Causes compilation error
Meats = {"Roast beef", "Salami", "Turkey", "Ham", "Pastrami" };

// Also causes compilation error
string[] Meats2;
Meats2 = {"Roast beef", "Salami", "Turkey", "Ham", "Pastrami" };

就个人而言,如果您明确声明变量的类型,我建议使用第二种语法声明变量,如下所示:

string[] Meats = {"Roast beef", "Salami", "Turkey", "Ham", "Pastrami" };

如果您倾向于使用var关键字,我会推荐第一种语法,因为它更清楚您期望结果是什么类型(可读性)并强制编译器也为您检查,如下所示:

var Meats = new string[]{"Roast beef", "Salami", "Turkey", "Ham", "Pastrami" };

一般来说,最好选择一种风格并保持一致。

于 2013-04-19T14:21:56.427 回答