Two methods that differ only in LINQ where part - delegate?
I have a method:
internal List<int> GetOldDoctorsIDs
{
var Result = from DataRow doctor in DoctorTable.Rows
where doctor.Age > 30
select doctor.ID
List<int> Doctors = new List<int>();
foreach (int id in Result)
{
//Register getting data
Database.LogAccess("GetOldDoctorsID: " + id.ToString());
if (Database.AllowAccess(DoctorsTable, id))
{
Doctors.Add(id);
}
}
}
So this gets old doctors开发者_JS百科 and does other things. Now I would like to create method GetExpensiveDoctors. It will look like this above, but in place of:
where doctor.Age > 30
I will have:
where doctor.Cost > 30000
How to create elegant, object oriented solution for this? Should I use delegate or other thing?
If you modify your method so that a predicate parameter is included (see below), you can call the method with any filters you need as per helium's examples.
internal List<int> GetDoctorsIDs(Predicate<DataRow> doctorFilter)
{
var Result = from DataRow doctor in DoctorTable.Rows
where doctorFilter(doctor)
select doctor.ID
List<int> Doctors = new List<int>();
foreach (int id in Result)
{
//Register getting data
Database.LogAccess("GetOldDoctorsID: " + id.ToString());
if (Database.AllowAccess(DoctorsTable, id))
{
Doctors.Add(id);
}
}
}
You could parameterize your method so it takes the condition as a function from DataRow to bool.
Than you could call
GetDoctorsIDs(doctor => doctor.Age > 30);
or
GetDoctorsIDs(doctor => doctor.Cost > 30000);
You can add the where clause selectively, for example:
var Result = from DataRow doctor in DoctorTable.Rows
select doctor.ID;
if(getByAge) {
Result=Result.Where(doctor => doctor.Age>30);
} else {
Result=Result.Where(doctor => doctor.Cost>30000);
}
where getByAge
would be for example a boolean parameter on your method.
EDIT. If you need to parametrize the where clause, something like this should work:
internal List<int> GetOldDoctorsIDs(Func<Doctor, bool> whereClause)
{
var Result = DoctorTable.Rows.Where(d => whereClause(d)).Select(d => d.ID);
//etc...
}
then you invoke the method the way helium has said.
I've managed to do this in this way:
internal List<int> GetOldDoctorsIDs()
{
return GetDoctorsIDs((doctor) => doctor.Age > 30);
}
internal List<int> GetExpensiveDoctorsIDs()
{
return GetDoctorsIDs((doctor) => doctor.Cost > 30000);
}
internal List<int> GetDoctorsIDs(Func<DataRow, bool> Condition)
{
var Result = from DataRow doctor in DoctorTable.Rows
where Condition(doctor)
select doctor.ID
List<int> Doctors = new List<int>();
foreach (int id in Result)
{
//Register getting data
Database.LogAccess("GetOldDoctorsID: " + id.ToString());
if (Database.AllowAccess(DoctorsTable, id))
{
Doctors.Add(id);
}
}
}
精彩评论