6

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
}
11
  • you want to create objects in different names> Commented Nov 20, 2015 at 7:18
  • 2
    yes it is possible, be more specific what's the problem you are facing? Commented Nov 20, 2015 at 7:18
  • why you need creation of objects inside array? Commented Nov 20, 2015 at 7:18
  • Well, that depends on what you are trying to do with this object within your loop. Commented Nov 20, 2015 at 7:18
  • It is possible, but can you be more specific what you trying to achieve Commented Nov 20, 2015 at 7:18

2 Answers 2

7

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.

Sign up to request clarification or add additional context in comments.

12 Comments

I don't think that my original code is fine :( Because somehow the first object gets always lost when I go a second time through the loop.
@xileb0 see problem number 1 that is the life span of the variable. If you define a variable inside a block it is only valid / living through the blocks execution once and then gets recreated (in case of a loop block). msdn.microsoft.com/en-us/library/aa691170(v=vs.71).aspx a bit on that topic.
Ok i understand what you mean, but is there a way to solve this problem without an array/list? I don't have an dispose functionality btw.
from how I understand what you want to do is: Create a new object inside the loop then use it INSIDE the loop for a thread that is run and then reate the next object. Is that correct so? If so then your original code is just fine as the variable still has a reference set to the original address it had in memory (in the thread where you gave it as a parameter). Thus it would still live on inside the thread while in the original loop the variable with that name is set to a new value (not affecting the value you have inside the thread).
Check my new edit pls. That is exactly what I want to do. So I'd like to have for example 20 threads and everyone of them does something with a specific object. I think you understood it wrong. You thought I always only want to work with one object at the same time.
|
3

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.