【问题标题】:All possible array initialization syntaxes所有可能的数组初始化语法
【发布时间】:2011-08-06 09:35:09
【问题描述】:

C# 可以使用的所有数组初始化语法有哪些?

【问题讨论】:

    标签: c# arrays syntax array-initialization


    【解决方案1】:

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

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

    请注意,还有其他获取数组的技术,例如 IEnumerable<T> 上的 Linq ToArray() 扩展。

    还要注意,在上面的声明中,前两个可以用var (C# 3+) 替换左边的string[],因为右边的信息足以推断出正确的类型。第三行必须按显示写,因为仅靠数组初始化语法不足以满足编译器的要求。第四个也可以使用推理。因此,如果您对整个简洁性感兴趣,则上述内容可以写为

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

    【讨论】:

    • 出于好奇,有人能解释一下为什么第 3 行中的初始化表达式不能单独使用(例如传递给方法)或分配给var 变量吗?
    • @Ruben9922:有趣的问题。如果数组初始值设定项可以产生除数组以外的任何其他东西,那么var x = {} 不起作用是有道理的,但我不知道那是什么。所以我猜数组初始化器是一种语言特性。如果你将它与new List<string> {"A", "B"}一起使用,它也会产生不同的结果。
    • 是否有任何理由使用string array = new string[] { "A", "B" }; 而不是string array = { "A", "B" };?第一个似乎是多余的。
    • @Lou 语法来自于显式指定类型的能力,以防无法自动推断。但当然,对于原始字符串类型,这种表示法肯定显得多余
    • @Ruben9922:有趣的是,Dim a = { "A", "B" } 确实在 VB.NET 中工作(使用 Option Strict On 和 Option Infer On)并正确推断出 String() (string[] in C#) 作为数据类型,所以我猜 C# 设计者故意选择不支持这一点。我想在 VB 中实现起来更容易,因为 VB 只使用花括号进行数组初始化(与 C# 不同,C# 到处都有花括号)。在VB中,也可以在返回数组的方法中写Return {}
    【解决方案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 节“数组创建表达式”。

    【讨论】:

    • @BoltClock:您提到的第一个语法是“隐式类型数组创建表达式”。第二个是“匿名对象创建表达式”。您没有列出其他两种类似的语法;它们是“对象初始化器”和“集合初始化器”。
    • 不完全是 C#“语法”,但我们不要忘记(我个人最喜欢的)Array.CreateInstance(typeof(int), 3)
    • @Jeffrey:如果我们沿着这条路走,它就会开始变得愚蠢。例如,"1,2,3,4".split(',').
    • 那么对于多维数组,存在像new int[,] { { 3, 7 }, { 103, 107 }, { 10003, 10007 }, };这样的“嵌套”符号,以此类推int[,,],int[,,,],...
    • @Learning-Overthinker-Confused:你有两匹马。您想知道哪个更快。您是否(1)与马赛跑,或(2)在互联网上询问从未见过马的陌生人他认为哪一匹更快? 赛马。你想知道哪个更“高效”吗?首先建立一个可衡量的效率标准;请记住,效率是每单位成本产生的价值,因此请仔细定义您的价值和成本。然后双向编写代码并衡量其效率。 用科学来回答科学问题,不要随便问陌生人猜测。
    【解决方案3】:

    非空数组

    • 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({}) 不可编译

    【讨论】:

    • 最好将无效语法与有效语法更清楚地分开。
    • 给定的例子是否完整?还有其他情况吗?
    【解决方案4】:
    Enumerable.Repeat(String.Empty, count).ToArray()
    

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

    【讨论】:

    • 是的,在var arr1 = Enumerable.Repeat(new object(), 10).ToArray(); 中,您获得了对同一对象的 10 个引用。要创建 10 个不同的对象,您可以使用 var arr2 = Enumerable.Repeat(/* dummy: */ false, 10).Select(x => new object()).ToArray(); 或类似名称。
    【解决方案5】:

    如果你想初始化一个预先初始化的相等(非nulldefault以外的)元素的固定数组,使用这个:

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

    也请参与this讨论。

    【讨论】:

      【解决方案6】:
      var contacts = new[]
      {
          new 
          {
              Name = " Eugene Zabokritski",
              PhoneNumbers = new[] { "206-555-0108", "425-555-0001" }
          },
          new 
          {
              Name = " Hanying Feng",
              PhoneNumbers = new[] { "650-555-0199" }
          }
      };
      

      【讨论】:

      • 你应该如何使用这个结构?像字典吗?
      • @R.Navega 这是一个普通的数组 :)
      • @grooveplex 这是一个匿名类型的数组。匿名类型包含字符串类型的成员名称和字符串[] 类型的电话号码。类型由编译器推断。
      【解决方案7】:

      创建自定义类数组的示例

      下面是类定义。

      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"
          }
      };
      

      【讨论】:

        【解决方案8】:

        重复没有LINQ

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

        【讨论】:

          【解决方案9】:
          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 Integer
              Dim 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)"
          

          【讨论】:

          • 您好,最后一个示例块似乎是 Visual Basic,问题要求提供 c# 示例。
          【解决方案10】:

          只是一个注释

          以下数组:

          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" };
          

          【讨论】:

            【解决方案11】:
            For Class initialization:
            var page1 = new Class1();
            var page2 = new Class2();
            var pages = new UIViewController[] { page1, page2 };
            

            【讨论】:

              【解决方案12】:

              另一种创建和初始化对象数组的方法。这类似于example which @Amol has posted above,除了这个使用构造函数。一点点多态性洒进来,我无法抗拒。

              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 set
                  string 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;
              }
              

              【讨论】:

                【解决方案13】:

                对于以下课程:

                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") };
                

                希望这会有所帮助。

                【讨论】:

                  【解决方案14】:

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

                  你可以使用这种形式如果你想生成一个指定范围 0 到 9 范围内的整数序列:

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

                  【讨论】:

                    【解决方案15】:

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

                    对于字符串

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

                    对于号码

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

                    【讨论】:

                      【解决方案16】:

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

                      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 n
                      Console.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();
                      

                      【讨论】:

                        【解决方案17】:

                        带有表达式的简单解决方案。请注意,使用 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
                        

                        【讨论】:

                          猜你喜欢
                          • 1970-01-01
                          • 2015-01-04
                          • 1970-01-01
                          • 1970-01-01
                          • 2016-03-03
                          • 2011-05-09
                          • 1970-01-01
                          相关资源
                          最近更新 更多