I\'m struggling with some Generic constraint issues when trying to implement a library that allows inheritance and hoping someone can help.
I\'m trying to build up a cl
It's a piece of generic cake. You need to define the generic classes in terms of themselves. A recursive generic definition.
Base Classes:
public class Generic_Element
where E : Generic_Element
{
}
/// Visit to a Generic_Element
public class Generic_Visit
where V : Generic_Visit
where E : Generic_Element
{
public E Element { get; set; }
}
/// Collection of Visits
public class Generic_Route
where R : Generic_Route
where V : Generic_Visit
where E : Generic_Element
{
public List Visits { get; set; }
public Double Distance { get; set; }
}
/// Collection of Routes
public class Generic_Solution
where S : Generic_Solution
where R : Generic_Route
where V : Generic_Visit
where E : Generic_Element
{
public List Routes { get; set; }
public Double Distance
{
get
{
return this.Routes.Select(r => r.Distance).Sum();
}
}
}
TSP Classes:
public class Generic_Tsp_Element : Generic_Element
where E : Generic_Tsp_Element
{
}
/// Visit to a Generic_Element
public class Generic_Tsp_Visit : Generic_Visit
where V : Generic_Tsp_Visit
where E : Generic_Tsp_Element
{
public Double Time { get; set; }
}
/// Collection of Visits
public class Generic_Tsp_Route : Generic_Route
where R : Generic_Tsp_Route
where V : Generic_Tsp_Visit
where E : Generic_Tsp_Element
{
public Double Time
{
get
{
return this.Visits.Select(v => v.Time).Sum();
}
}
}
/// Collection of Routes
public class Generic_Tsp_Solution : Generic_Solution
where S : Generic_Tsp_Solution
where R : Generic_Tsp_Route
where V : Generic_Tsp_Visit
where E : Generic_Tsp_Element
{
public Double Time
{
get
{
return this.Routes.Select(r => r.Time).Sum();
}
}
}
public class Concrete_Tsp_Element : Generic_Tsp_Element { }
public class Concrete_Tsp_Visit : Generic_Tsp_Visit { }
public class Concrete_Tsp_Route : Generic_Tsp_Route { }
public class Concrete_Tsp_Solution : Generic_Tsp_Solution { }
VRP Classes:
public class Generic_Vrp_Element : Generic_Element
where E : Generic_Vrp_Element
{
}
/// Visit to a Generic_Element
public class Generic_Vrp_Visit : Generic_Visit
where V : Generic_Vrp_Visit
where E : Generic_Vrp_Element
{
public Double Capacity { get; set; }
}
/// Collection of Visits
public class Generic_Vrp_Route : Generic_Route
where R : Generic_Vrp_Route
where V : Generic_Vrp_Visit
where E : Generic_Vrp_Element
{
public Double Capacity
{
get
{
return this.Visits.Select(v => v.Capacity).Sum();
}
}
}
/// Collection of Routes
public class Generic_Vrp_Solution : Generic_Solution
where S : Generic_Vrp_Solution
where R : Generic_Vrp_Route
where V : Generic_Vrp_Visit
where E : Generic_Vrp_Element
{
public Double Capacity
{
get
{
return this.Routes.Select(r => r.Capacity).Sum();
}
}
}
public class Concrete_Vrp_Element : Generic_Vrp_Element { }
public class Concrete_Vrp_Visit : Generic_Vrp_Visit { }
public class Concrete_Vrp_Route : Generic_Vrp_Route { }
public class Concrete_Vrp_Solution : Generic_Vrp_Solution { }
The final result is non-generic concrete classes that can be used like this:
var e = new Concrete_Tsp_Element();
var v = new Concrete_Tsp_Visit();
v.Element = e;
v.Time = 0.5;
var r = new Concrete_Tsp_Route();
r.Visits = new List(new[] { v });
r.Distance = 2.1;
var s = new Concrete_Tsp_Solution();
s.Routes = new List(new[] { r });
Console.WriteLine(s.Distance);
Console.WriteLine(s.Time);
Console.ReadLine();
Enjoy! Enjoy!