Basically your data structures differ in a "generic" parameter. So you would need a generic interface to accomodate for this, or you could use a generic class and get rid of DgDictHosp
and DgDictOper
altogether because the generic class could account for all properties:
public class DgDictBaseClass<T> where T : HospOpBase
{
public long Key { get; set; }
public IOrderedEnumerable<T> Data { get; set; }
public List<string> List { get; set; }
}
I restricted the generic parameter to a baseclass that I introduced to simplify the code of the classes Hospitalization
and Operation
:
public abstract class HospOpBase
{
public int ID { get; set; }
public int IDDiagnosis { get; set; }
}
public class Hospitalization : HospOpBase
{
public long IDHospitalization { get; set; }
}
public class Operation : HospOpBase
{
public long IDOperation { get; set; }
}
With these tools in your backback you can now start to make your mapping method generic to accomodate for both types of collections. As a parameter you would now pass a List<DgDictBaseClass<T>> list_g
and you will return Dictionary<long, DictItem>
:
public static Dictionary<long, DictItem> ConvertToDictionary<T>(List<DgDictBaseClass<T>> list_g) where T : HospOpBase
{
var res_dict = list_g.Select(q => new DictItem
{
Id = q.Key,
List = q.Data.Select(t => ToLiteral(t.IDDiagnosis)).ToList()
}).ToDictionary(k => k.Id);
return res_dict;
}
Here again it is usefull to restrict the generic parameter T
to be of type HospOpBase
. This way the compiler will know that it has the property IDDiagnosis
and you can use it in your linq statement.
Now there is only 1 last change to be made to your current code. Since I got rid of the classes DgDictOper
and DgDictHosp
entirely you need to exchange them with the new type in the methods: GetHospDict
and GetOperDict
in the select statement :
public static Dictionary<long, DictItem> GetHospDict(List<Hospitalization> list)
{
var res_g =
(from dg in list
group dg by dg.IDHospitalization
into dg_group
select new DgDictBaseClass<Hospitalization> // <= change here
{
Key = dg_group.Key,
Data = dg_group.OrderBy(g => g.ID)
}).ToList();
var res = ConvertToDictionary(res_g);
return res;
}
public static Dictionary<long, DictItem> GetOperDict(List<Operation> list)
{
var res_g =
(from dg in list
group dg by dg.IDOperation
into dg_group
select new DgDictBaseClass<Operation> // <= change here
{
Key = dg_group.Key,
Data = dg_group.OrderBy(g => g.ID)
}).ToList();
var res = ConvertToDictionary(res_g);
return res;
}
EDIT:
actually there is a way to combine the last 2 mapping methods into 1. The tricky part here is the grouping variable which is actually the only difference in the two methods. You can provide this method as a method parameter. The type is either Func<Operation, long>
or Func<Hospitalization, long>
. (Which basically means that it is a method that takes an Operation
as input parameter and returns a long
, in your case the property: dg.IDOperation
). So since the 2 classes have now a common base class we can make the method generic, the grouping function parameter of type: Func<T, long>
and restrict the generic parameter to be only of type HospOpBase
. Now the function would look like this:
public static Dictionary<long, DictItem> GetOperDictNew<T>(List<T> list, Func<T, long> groupingFilter) where T : HospOpBase
{
var res_g =
(from dg in list
group dg by groupingFilter(dg) // <= use here the grouping filter
into dg_group
select new DgDictBaseClass<T>
{
Key = dg_group.Key,
Data = dg_group.OrderBy(g => g.ID)
}).ToList();
var res = ConvertToDictionary(res_g);
return res;
}
Now you can call the new method in both loops:
foreach (var x in GetOperDictNew(InitHospList(), x => x.IDHospitalization))
{
Console.WriteLine("Hosp ID: " + x.Key);
foreach (var y in x.Value.List)
{
Console.WriteLine("Diagosis: " + y); ;
}
}
foreach (var x in GetOperDictNew(InitOperList(), x => x.IDOperation))
{
Console.WriteLine("Operation ID: " + x.Key);
foreach (var y in x.Value.List)
{
Console.WriteLine("Diagosis: " + y); ;
}
}
and you will get the same output:
Hosp ID: 11
Diagosis: dictionary phrase for 10
Diagosis: dictionary phrase for 20
Operation ID: 22
Diagosis: dictionary phrase for 30
Diagosis: dictionary phrase for 40