Me Myself & C#

Manoj Garg’s Tech Bytes – What I learned Today

Archive for the ‘Collections & Generics’ Category

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 »

Using Predicates with List.Find()

Posted by Manoj Garg on July 16, 2007

Yesterday, One of my team member had a requirement for searching a List for an object having a specific value for one of its member. After some googling I found out few links explaining use of Predicates for this kind of custom searching. It solved my purpose.. so here goes how I did it 🙂

For example, we have a class Employee with members like EmpCode, First Name , Last Name etc.

public class Employee{    
    //Private members for all the below described properties
    //Public Properties   
    public String EmpCode;    
    public String FirstName;    
    public String LastName;    
    public DateTime DateOfBirth;
    public String Department;
    public String Designation;
    //Methods

    //Constructor
    public Employee(String ecode, String fname, String lname, DateTime dob, String dept, String desg)
    {
         EmpCode = ecode;
         FirstName = fname;
         LastName = lname;
         DateOfBirth = dob;
         Department = dept;
         Designation = desg;    
    }
}
 
and we have a list of Employee objects..

public class EmployeeList : List<Employee>
{ }
 

Now suppose we have a list of employees and we want to search them on the basis of their first name. There are two ways to do it.

  1. we iterate through the complete list and compare each Employee object’s FirstName property to our required value
  2. Or, we can use predicates to search the intended objects.

Following code snippet shows how to use predicate in List.Find() method

EmployeeList elist = new EmployeeList();
elist.Add(new Employee("1","Mk","Garg",DateTime.Now,"ITG","Arch"));
elist.Add(new Employee("2","P","Jain",DateTime.Now,"SE","Engg"));
elist.Add(new Employee("3","A","Goyal",DateTime.Now,"QA","Lead"));
elist.Add(new Employee("4","Bob","Matt",DateTime.Now,"HR","Mgr"));

//Find Using Inline
Employee em = elist.Find(delegate(Employee e) { return e.FirstName == "Mk"; });

Here in the above code em will have the Employee object with FirstName = “Mk”

Output will be

Prdicate example output 

These predicates can be used as annonymous functions as we used in the above code function, or  we can define a function which accepts an Object of type, we want to search, as parameter, and it returns bool value indicating whether a record mathed the criteria specified. it is a static method.  For example, in our code suppose we want to search the employees by their designation we can do it like :

Employee edesg = elist.Find(FindByDesignation);

Here FindByDesignation is a method which looks like:

private static bool FindByDesignation(Employee e){return (e.Designation == “Lead”);}

Ha-P Coding 🙂

Posted in C#, Collections & Generics, Delegates | Tagged: , , , | 16 Comments »