Generic foreach loop for different property
-
21-12-2019 - |
Question
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?
Solution
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);
OTHER TIPS
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.