【问题标题】:Assigning custom objects to array with a for loop?使用for循环将自定义对象分配给数组?
【发布时间】:2010-06-14 18:49:02
【问题描述】:

鉴于此example

 // Create an arary of car objects.      
     car[] arrayOfCars= new car[]
     {
        new car("Ford",1992),
        new car("Fiat",1988),
        new car("Buick",1932),
        new car("Ford",1932),
        new car("Dodge",1999),
        new car("Honda",1977)
     };

我尝试过这样的事情:

for (int i = 0; i < dtable.Rows.Count; i++)
{
    DataRow drow = dtable.Rows[i];
    arrayOfCars[] =  new car(drow["make"].ToString(), drow["year"].ToString());
}

如何在循环遍历数据表时向数组中添加额外的数据?

更新1:

我选择了@Reed 提出的解决方案。

// Create the array, specifying the total length 
car[] arrayOfCars = new car[dtable.Rows.Count]; 

for (int i = 0; i < dtable.Rows.Count; i++) 
{ 
    DataRow drow = dtable.Rows[i]; 
    // Assign each car to the specific index within the array (arrayOfCars[i]) 
    arrayOfCars[i] =  new car(drow["make"].ToString(), drow["year"].ToString()); 
} 

【问题讨论】:

  • arrayOfCars[] = 让我猜猜,来自 PHP 背景?
  • @Adam Robinson - 不是作业。尝试修改与superlist.codeplex.com 相关的示例 提供的示例已静态定义所有数组。
  • @Bemrose - PHP 肯定具有破坏性影响。

标签: c# winforms arrays .net-3.5 datatable


【解决方案1】:

数组一旦创建就不能再添加元素了。不要使用数组,而是使用List&lt;car&gt;。这将让您调用 .Add 来添加元素。

例如:

 // Create an List of car objects.      
 List<car> listOfCars = new List<car>()
 {
    new car("Ford",1992),
    new car("Fiat",1988),
    new car("Buick",1932),
    new car("Ford",1932),
    new car("Dodge",1999),
    new car("Honda",1977)
 };

你可以这样做:

for (int i = 0; i < dtable.Rows.Count; i++)
{
    DataRow drow = dtable.Rows[i];
    listOfCars.Add(new car(drow["make"].ToString(), drow["year"].ToString()));
}

您可以像使用数组一样使用listOfCars,并通过索引访问元素:

car myCar = listOfCars[3];

如果您必须有一个数组,请在完成“添加到列表”后通过在列表上调用 ToArray() 来创建它:

// ... Add as above...
car[] arrayOfCars = listOfCars.ToArray(); // Creates an array from your list

编辑:

如果您只是尝试从 DataTable 分配和构造数组,并且在构造完成后不需要向其中添加元素,则可以使用数组,如下所示:

// Create the array, specifying the total length
car[] arrayOfCars = new car[dtable.Rows.Count];

for (int i = 0; i < dtable.Rows.Count; i++)
{
    DataRow drow = dtable.Rows[i];
    // Assign each car to the specific index within the array (arrayOfCars[i])
    arrayOfCars[i] =  new car(drow["make"].ToString(), drow["year"].ToString());
}

【讨论】:

  • 但是他好像提前知道数组项的个数,那为什么不初始化一个正确大小的数组呢?我相信混乱来自他试图使用数组初始值设定项语法将项目插入数组。
  • @dtb:是吗?从这个问题中不清楚他是完全从 DataTable 构建数组,还是手动构建它,然后从 DataTable 添加到它,可能在以后或以单独的方法添加......
  • 这是一个很好的点 dtb,他使用的是 DataTable,所以除非他做了一些疯狂的事情,否则你应该有一个固定的大小。当然,通过阅读这个例子,我不确定他是否太担心速度。
  • @dtb & @Matthew:只为你们 - 我在我的答案中添加了固定大小选项,但需要注意的是,它仅在您以后不打算尝试向数组中添加元素时才有效. :)
【解决方案2】:

一旦创建了数组,就不能再添加新元素了。但是,您可以将其中的元素重新分配给新对象。如果您想要新元素(以便您的数组增长),请使用(如前所述)通用:List&lt;T&gt;。如果您想重新分配已经存在的元素,请使用以下内容(我尚未编译此内容,因此您可能需要进行更改:)

for(int i = 0; i < dtable.Rows.Count; i++)
{
    DataRow drow = dtable.Rows[i];
    cars[i] = new car(drow["make"].ToString(), drow["model"].ToString());
}

【讨论】:

    【解决方案3】:

    数组不能就地调整大小。

    相反,您应该使用List&lt;Car&gt; 并调用Add,如下所示:

     List<car> cars= new List<car>()
     {
        new car("Ford",1992),
        new car("Fiat",1988),
        new car("Buick",1932),
        new car("Ford",1932),
        new car("Dodge",1999),
        new car("Honda",1977)
     };  //C# 3 collection initializer
    
    for (int i = 0; i < dtable.Rows.Count; i++)
    {
        DataRow drow = dtable.Rows[i];
        cars.Add(new car((string)drow["make"], (int)drow["year"]));
    }
    

    【讨论】:

    • System.Array.Resize&lt;...&gt;(...)
    • @Matthew Whited:Array.Resize 本质上是创建一个新数组,复制旧数组中的所有项目并返回新数组。它实际上并没有调整旧数组的大小。 List 封装了一个可以根据需要调整大小的数组,因此您不必自己调整数组的大小(并跟踪项目的实际数量等)
    • @Matthew,下一点是您不想在循环的每次迭代中调整数组的大小。因此,要么(a)使用列表,要么(b)在循环之前创建适当的大小。您可以获得调整大小的数组这一事实与这个问题并不特别相关。
    • msdn.microsoft.com/en-us/library/bb348051.aspx (我想我应该注意它需要数组的引用,以便您可以替换内容)。
    • @dtb,你把我带到了那里。所以数组的特定实例没有调整大小,而是从引用/值的角度来看。
    【解决方案4】:

    您也可以使用 LINQ 来执行此操作...

    var fromTable = from row in dtable.Rows.OfType<DataRow>()
                    let make = row["make"] as string
                    let year = (int)row["year"]
                    select new car(make, year);
    
    car[] arrayOfCars = listOfCars.Concat(fromTable).ToArray();
    

    ...如果 DataTable 中有大量行并且您想尝试挤出一些性能,您可以这样做...

    var makeIndex = dtable.Columns["make"].Ordinal;
    var yearIndex = dtable.Columns["year"].Ordinal;
    
    var fromTable = from row in dtable.Rows.OfType<DataRow>()
                    let items = row.ItemArray
                    let make = items[makeIndex] as string
                    let year = (int)items[yearIndex]
                    select new car(make, year);
    

    【讨论】:

      【解决方案5】:

      如果您知道其中总共有多少个元素,我只建议使用数组。否则,您最好使用 Reed 和 SLaks 建议的列表。

      【讨论】:

        【解决方案6】:

        如上所述 - 使用 List&lt;Car&gt; 拥有一个包含动态元素数量的列表 - 使用方法 Add(Car item) 添加新实例。请务必访问相应的 MSDN 站点:http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx

        顺便说一句:运算符 [] 在 C# 中不起作用,即使您使用例如创建了一个数组。 5 个元素,想添加第一个。

        【讨论】:

          【解决方案7】:

          如果您有 .NET 3.5,则使用 Array.Resize()。

          // Create an arary of car objects.      
               car[] arrayOfCars= new car[]
               {
                  new car("Ford",1992),
                  new car("Fiat",1988),
                  new car("Buick",1932),
                  new car("Ford",1932),
                  new car("Dodge",1999),
                  new car("Honda",1977)
               };    
          
          // resize the array...
          var rowCount = dtable.Rows.Count;
          var offSet = arrayOfCars.Length;
          Array.Resize<car>(ref arrayOfCars, rowCount + offSet);
          
          // populate the new (empty) array elements from the database...
          for (int i = 0; i < rowCount; i++)
          {
              DataRow drow = dtable.Rows[i];
              arrayOfCars[i + offSet] =  
                new car(drow["make"].ToString(), drow["year"].ToString());
          }
          

          【讨论】:

          • 我喜欢你的方法。扩展是固定大小的,所以这是最好的答案之一。 List&lt;...&gt; 版本可以工作,但取决于 DataTable 的大小,这可能会导致内部数组的多次扩展。但这些细节对性能的影响可能不及通过字符串索引名称提取列值的影响。所以我同意这个问题的语义是毫无意义的(但很有趣:o)
          猜你喜欢
          • 1970-01-01
          • 2018-11-18
          • 2018-11-13
          • 2020-12-15
          • 1970-01-01
          • 1970-01-01
          • 2021-02-07
          • 2019-10-29
          • 2020-02-25
          相关资源
          最近更新 更多