Generic foreach loop for different property

1.6k Views Asked by At

I am trying to use a generic method for foreach loop which would pass different parameter as the argument.

In this example below I would like to pass different parameters(EmployeeDisplayOrder or EmployeeEnrollOrder)

public void SaveEmployeeDisplayOrder(ICollection<Employee> employees)
{
   //some code

   foreach( var emp in employees)
   {
      UpdateSpecificEmployeeOrder(employee.id, e => e.EmployeeDisplayOrder);
   }
}

public void SaveEmployeeEnrollOrder(ICollection<Employee> employees)
{
   //some code

   foreach( var emp in employees)
   {
     UpdateSpecificEmployeeOrder(employee.id, e => e.EmployeeEnrollOrder);
   }
}

I would like to have something like this

public void UpdateEmployeeOrders(ICollection<Employee> employee)
{ 
  foreach( var emp in employees)
  {
    UpdateSpecificEmployeeOrder(employee.id, //generic property);
  }
}

and call this UpdateEmployeeOrders generic method from SaveEmployeeDisplayOrder and SaveEmployeeEnrollOrder.

Method signature for UpdateSpecificEmployeeOrder

UpdateSpecificEmployeeOrder( int employeeid, params Expression<Func<Employee, object>>[] property)

Is this possible?

2

There are 2 best solutions below

3
On BEST ANSWER

You have the answer in your answer... you're using lambdas... so pass a delegate in your method.

public void SaveEmployeeDisplayOrder<T>(ICollection<Employee> employees, Func<Employee, T> fetchProperty)
{
   //some code

   foreach( var employee in employees)
   {
      UpdateSpecificEmployeeOrder(employee.id, fetchProperty(employee));
   }
}

Then you would call it similar to what you had:

SaveEmployeeDisplayOrder(employees, e => e.EmployeeDisplayOrder);

or

SaveEmployeeDisplayOrder(employees, e => e.EmployeeEnrollOrder);
5
On

Have the method accept an expression, just as the method you're passing it to does:

public class Foo
{
    public void UpdateEmployeeOrders(IEnumerable<Employee> employees,
         Expression<Func<Employee, object>> selector)
    {
        foreach (var employee in employees)
        {
            UpdateSpecificEmployeeOrder(employee.id, selector);
        }
    }
}

Also, since the only thing we ever do with employees is iterate over it, we can type the parameter as IEnumerable instead of ICollection. It provides all of the guarantees that this methods needs, while allowing a broader range of possible input types.