Me Myself & C#

Manoj Garg’s Tech Bytes – What I learned Today

Posts Tagged ‘pass by ref’

Passing an object by REF inside a foreach loop

Posted by Manoj Garg on April 22, 2009

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

Advertisements

Posted in C#, Collections & Generics | Tagged: | Leave a Comment »