所有可能的数组初始化语法

C#可以使用的所有数组初始化语法是什么?

797656 次浏览

这些是简单数组的当前声明和初始化方法。

string[] array = new string[2]; // creates array of length 2, default valuesstring[] array = new string[] { "A", "B" }; // creates populated array of length 2string[] array = { "A" , "B" }; // creates populated array of length 2string[] array = new[] { "A", "B" }; // created populated array of length 2

请注意,存在其他获取数组的技术,例如IEnumerable<T>上的LinqToArray()扩展。

另请注意,在上面的声明中,前两行可以将左侧的string[]替换为var(C#3+),因为右侧的信息足以推断正确的类型。第三行必须按照显示的方式编写,因为仅靠数组初始化语法不足以满足编译器的要求。第四行也可以使用推理。所以如果你是为了简洁起见,上面的内容可以写成

var array = new string[2]; // creates array of length 2, default valuesvar array = new string[] { "A", "B" }; // creates populated array of length 2string[] array = { "A" , "B" }; // creates populated array of length 2var array = new[] { "A", "B" }; // created populated array of length 2

C#中表达式的数组创建语法是:

new int[3]new int[3] { 10, 20, 30 }new int[] { 10, 20, 30 }new[] { 10, 20, 30 }

在第一个中,大小可以是任何非负整数值,并且数组元素被初始化为默认值。

在第二个中,大小必须是常量,给定的元素数量必须匹配。必须有从给定元素到给定数组元素类型的隐式转换。

在第三种情况下,元素必须隐式转换为元素类型,并且大小由给定元素的数量确定。

在第四个中,数组元素的类型是通过计算所有给定元素中具有类型的最佳类型(如果有)来推断的。所有元素都必须隐式转换为该类型。大小由给定元素的数量决定。这种语法是在C#3.0中引入的。

还有一种语法只能在声明中使用:

int[] x = { 10, 20, 30 };

元素必须隐式转换为元素类型。大小由给定元素的数量决定。

没有一体化的指南

请参阅C#4.0规范7.6.10.4“数组创建表达式”部分。

int[] array = new int[4];array[0] = 10;array[1] = 20;array[2] = 30;

string[] week = new string[] {"Sunday","Monday","Tuesday"};

string[] array = { "Sunday" , "Monday" };

和多维数组

    Dim i, j As IntegerDim strArr(1, 2) As String
strArr(0, 0) = "First (0,0)"strArr(0, 1) = "Second (0,1)"
strArr(1, 0) = "Third (1,0)"strArr(1, 1) = "Fourth (1,1)"
Enumerable.Repeat(String.Empty, count).ToArray()

将创建重复计数次数的空字符串数组。如果您想使用相同但特殊的默认元素值初始化数组。小心引用类型,所有元素都将引用同一个对象。

非空数组

  • var data0 = new int[3]

  • var data1 = new int[3] { 1, 2, 3 }

  • var data2 = new int[] { 1, 2, 3 }

  • var data3 = new[] { 1, 2, 3 }

  • var data4 = { 1, 2, 3 }不可编译。改用int[] data5 = { 1, 2, 3 }

空数组

  • var data6 = new int[0]
  • var data7 = new int[] { }
  • var data8 = new [] { }int[] data9 = new [] { }是不可编译的。

  • var data10 = { }不可编译。改用int[] data11 = { }

作为方法的参数

只有可以使用var关键字分配的表达式才能作为参数传递。

  • Foo(new int[2])
  • Foo(new int[2] { 1, 2 })
  • Foo(new int[] { 1, 2 })
  • Foo(new[] { 1, 2 })
  • Foo({ 1, 2 })不可编译
  • Foo(new int[0])
  • Foo(new int[] { })
  • Foo({})不可编译
var contacts = new[]{new{Name = " Eugene Zabokritski",PhoneNumbers = new[] { "206-555-0108", "425-555-0001" }},new{Name = " Hanying Feng",PhoneNumbers = new[] { "650-555-0199" }}};

如果您想初始化预初始化的等于(非nulldefault以外的)元素的固定数组,请使用:

var array = Enumerable.Repeat(string.Empty, 37).ToArray();

也请参加这个讨论。

重复LINQ

float[] floats = System.Array.ConvertAll(new float[16], v => 1.0f);

示例创建自定义类的数组

下面是类的定义。

public class DummyUser{public string email { get; set; }public string language { get; set; }}

这就是初始化数组的方式:

private DummyUser[] arrDummyUser = new DummyUser[]{new DummyUser{email = "abc.xyz@email.com",language = "English"},new DummyUser{email = "def@email.com",language = "Spanish"}};

您还可以创建动态数组,即您可以在创建数组之前先向用户询问数组的大小。

Console.Write("Enter size of array");int n = Convert.ToInt16(Console.ReadLine());
int[] dynamicSizedArray= new int[n]; // Here we have created an array of size nConsole.WriteLine("Input Elements");for(int i=0;i<n;i++){dynamicSizedArray[i] = Convert.ToInt32(Console.ReadLine());}
Console.WriteLine("Elements of array are :");foreach (int i in dynamicSizedArray){Console.WriteLine(i);}Console.ReadKey();

带有表达式的简单解决方案。请注意,使用NewArrayInit,您只能创建一维数组。

NewArrayExpression expr = Expression.NewArrayInit(typeof(int), new[] { Expression.Constant(2), Expression.Constant(3) });int[] array = Expression.Lambda<Func<int[]>>(expr).Compile()(); // compile and call callback

另一种创建和初始化对象数组的方法。这类似于@Amol在上面发布的示例,除了这个使用构造函数。撒了一点多态性,我无法抗拒。

IUser[] userArray = new IUser[]{new DummyUser("abc@cde.edu", "Gibberish"),new SmartyUser("pga@lna.it", "Italian", "Engineer")};

上下文类:

interface IUser{string EMail { get; }       // immutable, so get only an no setstring Language { get; }}
public class DummyUser : IUser{public DummyUser(string email, string language){m_email = email;m_language = language;}
private string m_email;public string EMail{get { return m_email; }}
private string m_language;public string Language{get { return m_language; }}}
public class SmartyUser : IUser{public SmartyUser(string email, string language, string occupation){m_email = email;m_language = language;m_occupation = occupation;}
private string m_email;public string EMail{get { return m_email; }}
private string m_language;public string Language{get { return m_language; }}
private string m_occupation;}
For Class initialization:var page1 = new Class1();var page2 = new Class2();var pages = new UIViewController[] { page1, page2 };

对于下面的类:

public class Page{
private string data;
public Page(){}
public Page(string data){this.Data = data;}
public string Data{get{return this.data;}set{this.data = value;}}}

您可以初始化上述对象的数组,如下所示。

Pages = new Page[] { new Page("a string") };

希望这有帮助。

只是一张纸条

以下数组:

string[] array = new string[2];string[] array2 = new string[] { "A", "B" };string[] array3 = { "A" , "B" };string[] array4 = new[] { "A", "B" };

将是编译到:

string[] array = new string[2];string[] array2 = new string[] { "A", "B" };string[] array3 = new string[] { "A", "B" };string[] array4 = new string[] { "A", "B" };

只是添加另一种方式:从这个页面:https://learn.microsoft.com/it-it/dotnet/api/system.linq.enumerable.range?view=netcore-3.1

您可以使用此表单如果您想在指定的范围strat 0到9内生成整数序列:

using System.Linq.....public int[] arrayName = Enumerable.Range(0, 9).ToArray();

要初始化一个空数组,它应该是dotnet 5.0中的Array.Empty<T>()

对于字符串

var items = Array.Empty<string>();

对于数字

var items = Array.Empty<int>();

另一种方法是调用静态函数(用于静态对象)或实例对象的任何函数。这可用于成员初始化。

现在我还没有测试所有这些,所以我将把我测试过的(静态成员和静态函数)

Class x {private static Option[] options = GetOptionList();private static Option[] GetOptionList() {
return (someSourceOfData).Select(dataitem => new Option(){field=dataitem.value,field2=dataitem.othervalue});}}

我想知道的是是否有一种方法可以绕过函数声明。我知道在这个例子中它可以直接使用,但假设函数有点复杂,不能简化为单个表达式。

我想象像下面这样的事情(但它不起作用)

Class x {private static Option[] options = () => {Lots of prep stuff here that means we can not just use the next linereturn (someSourceOfData).Select(dataitem => new Option(){field=dataitem.value,field2=dataitem.othervalue});}}

基本上是一种为填充变量的范围声明函数的方法。如果有人能告诉我怎么做,我会很高兴的。

对于C#中的多维数组声明和赋值。

public class Program{static void Main(){char[][] charArr = new char[][] { new char[] { 'a', 'b' }, new char[] { 'c', 'd' } };
int[][] intArr = new int[][] { new int[] { 1, 2 }, new int[] { 3, 4 } };}
}