Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating new object in loop

Tags:

c#

I am having a little C# beginner problem. But I'm pretty sure that it is easy to solve.

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

If i do it like that, the object testObj gets overwritten everytime i go through the loop. Is it possible to don't overwrite it everytime? Or do I have to use an array?

Edit: Ok sorry, I'll try to be more specific: My goal is that I create some objects in this loop and then I call a new thread with every object. There I want to do something with the object and when I'm done I'd like to release it.

Edit2 for Thomas:

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
}
like image 866
xileb0 Avatar asked Jan 08 '23 03:01

xileb0


2 Answers

Your problems are two fold.

  1. Lifespan of the variable. A local variable only lives in the block it is defined in. Thus you defined testObj inside the foreach loop. Thus it only lives through one iteration of the block and ends to live at the end of the loop. The next iteration has a new testObj then.

Thus

object testObj 

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

Would solve this as testObj is defined outside the loop and thus regardless of iteration lives with the values set.

Then

  1. You always set it anew. If you set a variable to a new value the old value is overwritten with the new value. Thus you would have to use lists, arrays, ... if you want to save every testObj you create (or use 1 variable for each testObj but normally that is something only complete beginners do. Only mentioning it for completeness sake and to mention that it is something not to do as it will enlarge your overhead greatly).

So you could do:

List testObjList = new List();

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

If you add it directly into the list (Add(new object)) you can acces it by using testObjList[testObjList.Count - 1] (count-1 as indexes begin with 0 and not 1). This is then the same as when you use testObj of the second variant.

Edit: For using them inside threads and then eliminating these objects you have 2 options.

1.) The object does not have any functionality for dispose then your original code is fine there:

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

The object is lost when the block ends BUT the garbage collector decides when it is really deleted (there are some exceptions like images where it can be that you need to do special operations in order to be able to delete them though).

If your object is of a specific class (lets call it myobject to not confuse it with the normal object) that has a dispose functionality it offers:

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

This means that the myObject object is only living within the using block and additionally when the block ends (even if through an exception) the dispose part is executed, which should make sure that the garbage collector is able to free the memory.

like image 87
Thomas Avatar answered Jan 09 '23 18:01

Thomas


It is perfectly OK to create new instances of your object with every iteration as the object IS only needed for the lifetime of one single life-cycle. Thus every thread you create gets its own instance of your testObj. If you´d want to do anything with the object AFTER the loop you have to cache it, either every instance by using an array or a list or only the last instance by using object testObject BEFORE the loop and assign it with every iteration new. This however will lead to the reference testObject containing only the last instance you created within the last iteration.

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);
like image 22
MakePeaceGreatAgain Avatar answered Jan 09 '23 17:01

MakePeaceGreatAgain