Reputation: 1906
Just was curious about below code.
for (int i=0; i<9; i++)
{
ClassA objectA = new ClassA();
}
or
ClassA objectA;
for (int i=0; i<9; i++)
{
objectA = new ClassA();
}
Any Idea is there any difference for both code ? from my knowledge both will create different instances each time so number of instances are going to same .. Any idea ?
Upvotes: 6
Views: 14262
Reputation: 8558
The number of instance is not incremented based on the codes. Both loops are just re-initializing a same variable the only difference is that on the first loop the instance variable is not accessible when it finishes the loop unlike on the second loop wherein the variable is declared outside the loop.
Upvotes: 2
Reputation: 8554
prakash, just for the sake of correctness/completeness: it's untrue that the variables won't be able to be accessed after the loop ends. We are usually assuming that the object being created is very simple, which might not be the case. For example, you can add the object to a global list inside the constructor, so all the objects are still accessible after the loop ends.
The relevant difference is the one pointed out by kbrinley, because you cannot use the variable (which is a object reference) outside the for scope (whatever is between { and }) on the first example. Since on the second one you declare the variable outside the loop, you can still use the variable.
As Marc Gravell said, the IL generated is the same for both, so there should be no difference in terms of performance, memory occupation, etc., for the loop.[1]
1: Since on the second example certainly retain a reference to the last variable, the Garbage Collector won't be able to free its space. So, after the loop ends, there will be subtle differences.
Upvotes: 0
Reputation: 1062600
Scoping aside (i.e. whether the variable exists outside of the loop) there is usually no difference, since .NET variables are actually (in the IL) all at the start of the method anyway. However, there is an exception: if you capture the variable (into an anonymous method / lambda), then it behaves differently - the capture is constructed to respect the C# declaration. So:
List<Action> actions = new List<Action>();
ClassA objectA;
for (int i=0;i<9;i++)
{
objectA= new ClassA();
actions.Add(delegate { Console.WriteLine(objectA.GetHashCode()); });
}
foreach(Action action in actions) action();
and:
List<Action> actions = new List<Action>();
for (int i=0;i<9;i++)
{
ClassA objectA= new ClassA();
actions.Add(delegate { Console.WriteLine(objectA.GetHashCode()); });
}
foreach(Action action in actions) action();
Will do different things (the first prints the same address-based hash-code 9 times; the second prints 9 different address-based hash-codes, indicating that in the second loop we've captured 9 different variables, instead of a single variable).
In both cases there are 9 ClassA
objects created - simply that we can't see 8 of them any more in the first case.
Upvotes: 25
Reputation: 3444
In the first snippet, objectA will not be accessible outside of the loop. Thus, if you wrote:
for (int i=0;i<9;i++)
{
ClassA objectA = new ClassA();
}
// This will not compile.
objectA.DoSomething();
You would receive a compile error. However, if you wrote the code as:
ClassA objectA;
for (int i=0;i<9;i++)
{
objectA= new ClassA();
}
// This will compile.
objectA.DoSomething();
The second code snippet will compile (assuming ClassA has a method named DoSomething()).
Upvotes: 1
Reputation: 39833
Actually, since you never save a reference to your objects that you create, each time you override objectA, you will have eliminated the previous example.
However, in the case of:
for (int i=0;i<9;i++)
{
ClassA objectA = new ClassA();
}
objectA
does not exist outside of the scope of the loop, and all of the objects you created will eventually be deleted by the garbage collector. It would be a syntax error to reference objectA
outside of the loop.
In contrast, in the case of:
ClassA objectA;
for (int i=0;i<9;i++)
{
objectA= new ClassA();
}
objectA
is a valid identifier outside of the loop, and the final instance of ClassA
created will remain after the loop is completed.
Upvotes: 2
Reputation: 269
The only difference is that objectA will point to an ClassA example after second loop. In both cases 9 objects will be created, but in first case all of them will be destroyed, and in second one - the last object will not.
Upvotes: 0
Reputation: 5945
The difference between the two is that after the for loop completes, the instance of ClassA from the last iteration (i=8) will be available to the rest of the function, while in the first version, it won't be.
Upvotes: 0
Reputation: 34128
The only difference is that in the second example, the last created instance will still be accessible after the loop
Upvotes: 13
Reputation: 86708
The big difference is if you create a closure inside the loop that captures objectA, and that closure escapes the loop. In other words, if objectA
is somehow visible outside the loop, then the first instance will have 9 different values after the loop ends, while the second one will only have the last value once the loop ends.
For example,
for (int i = 0; i < 9; i++)
{
ClassA objectA = new ClassA();
someFunc(() => objectA);
}
could have different visible results than
ClassA objectA;
for (int i = 0; i < 9; i++)
{
objectA = new ClassA();
someFunc(() => objectA);
}
Upvotes: 0