在循环中创建新对象

时间:2015-11-20 07:15:51

标签: c#

我有一点C#初学者问题。但我很确定它很容易解决。

foreach(var test in Tests)
{
     object testObj = new object();             
     //Do something with the object
}

如果我这样做,每次进行循环时,对象testObj都会被覆盖。是否有可能不是每次都覆盖它? 或者我必须使用数组吗?

编辑:好的抱歉,我会尝试更具体: 我的目标是在这个循环中创建一些对象然后用每个对象调用一个新线程。在那里,我想对这个对象做点什么,当我完成时,我想释放它。

托马斯的Edit2:

foreach (var test in Tests)
{
     object testObj = new object();
     //Set some properties of the object
     Thread t = new Thread(() => manager(testObj));  
     t.Start();
}

public void manager(object testObj)
{
    //Do something with the object

    //Release it
}

2 个答案:

答案 0 :(得分:7)

你的问题有两个问题。

  1. 变量的寿命。局部变量只存在于其定义的块中。因此,您在foreach循环中定义了testObj。因此,它只能通过块的一次迭代生效,并在循环结束时生效。下一次迭代会有一个新的testObj。
  2. 因此

    object testObj 
    
    foreach(var test in Tests)
    {
         testObj = new object();             
         //Do something with the object
    }
    

    将解决此问题,因为testObj是在循环外定义的,因此无论迭代是否与设置的值一起生效。

    然后

    1. 你总是重新设定它。如果将变量设置为新值,则旧值将被新值覆盖。因此,你必须使用列表,数组......如果你想保存你创建的每个testObj(或者为每个testObj使用1个变量,但通常这只是完全初学者所做的事情。仅为了完整起见而提及它并提及这是不应该做的事情,因为它会大大增加你的开销。)
    2. 所以你可以这样做:

      List testObjList = new List();
      
      foreach (var tests in Tests)
      {
          testObjList.Add(new object());
          // Or alternatively  object testObj = new object();  testObjList.Add(testObj);
      }
      

      如果将其直接添加到列表中(Add(新对象)),则可以使用testObjList[testObjList.Count - 1](count-1作为索引从0开始而不是1)来访问它。这与使用第二个变体的testObj时相同。

      编辑: 要在线程中使用它们然后消除这些对象,您有2个选项。

      1。)对象没有任何处理功能,那么原始代码就可以了:

      foreach(var test in Tests)
      {
           object testObj = new object();             
           //Do something with the object
      }
      

      当块结束时对象丢失但是垃圾收集器决定它何时被真正删除(有一些例外,例如图像可能需要你做特殊操作以便能够删除它们)。

      如果你的对象属于一个特定的类(让我们称之为myobject,而不是将它与普通对象混淆),它具有一个dispose功能:

      foreach(var test in Tests)
      {
           using (myObject testObj = new myObject())
           {             
               //Do something with the object
           }
      }
      

      这意味着myObject对象只存在于using块中,另外当块结束时(即使通过例外)执行dispose部分,这应该确保垃圾收集器能够释放内存。

答案 1 :(得分:2)

在每次迭代中创建对象的新实例是完全可以的,因为对象IS仅在一个生命周期的生命周期中需要。因此,您创建的每个线程都会获得自己的testObj实例。如果你想对循环之后的对象做任何事情,你必须通过使用一个数组或一个列表来对每个实例进行缓存,或者通过在循环之前使用object testObject来仅对最后一个实例进行缓存,并将其分配给每个实例。迭代新。但是,这将导致引用testObject仅包含您在上一次迭代中创建的最后一个实例。

object testObj;
foreach (var test in Tests)
{
     testObj = new object();  // creates a new instance every iteration
     //Set some properties of the object
     Thread t = new Thread(() => manager(testObj));  
     t.Start();
}

// do anything with the lastly created instance
DoSomething(testObject);