Its summer time in India and its hard to resist drowsiness in the afternoon specially when you had a heavy lunch. So this afternoon while I was trying to take a nap, no one was watching :P, a friend of mine pinged me on IM, and says “dude, can’t I pass an object as ref inside a foreach loop?”, well my first reaction was “of course you can!!! “ but then I realized that its an iterator and I can’t modify an object I am iterating on.
I opened a new instance of Visual Studio and create a new console application. In this application created a new class named testref with just two fields, one string and another one an int. In the main method created a generic list of type testref and filled it with five testref object. Then tried to loop through it and pass the loop variable as ref in a function. He was right, C# compiler throws an error “Cannot pass ‘xxyzobj’ as a ref or out argument because it is a ‘foreach iteration variable’”. following snippet shows the initial set of code
class Program
{class testref
{public string val { get; set; }public int a {get;set;}public testref(string s){val = s;a = 0;}}static void Main(string[] args){List<testref> testcol = new List<testref>();
testcol.Add(new testref("One"));testcol.Add(new testref("two"));testcol.Add(new testref("three"));testcol.Add(new testref("four"));testcol.Add(new testref("five"));foreach (testref s in testcol){MethodWithRef(ref s);
}Console.ReadLine();}static void MethodWithRef(ref testref str){str.val = str.val + " not";
str.a = (new Random()).Next();
}}In above code snippet, line in yellow will give the compilation error. Since this is a C# complier restriction there are couple of workaround to this situation.
- Have a temporary variable and then pass this variable as the ref parameter in the method:
testref tempObj;foreach (testref s in testcol){tempObj = s;MethodWithRef(ref tempObj);
}
- Use List.ForEach() method to apply an action on all the objects in the list:
// Inside the main method pass the function name
// you want to apply on each object
testcol.ForEach(MethodWithoutRef);//Method to be applied on all the objects
static void MethodWithoutRef(testref str){str.val = str.val + " not";
str.a = (new Random()).Next();
}So that was it.. problem was solved…
PS: If you have some more ways this can be solved, Please do share.
—
Manoj