This is a piece of birth cake. You must define common classes in terms of yourself. Recursive general definition.
Base classes:
public class Generic_Element<E> where E : Generic_Element<E> { } /// <summary>Visit to a Generic_Element</summary> public class Generic_Visit<V, E> where V : Generic_Visit<V, E> where E : Generic_Element<E> { public E Element { get; set; } } /// <summary>Collection of Visits</summary> public class Generic_Route<R, V, E> where R : Generic_Route<R, V, E> where V : Generic_Visit<V, E> where E : Generic_Element<E> { public List<V> Visits { get; set; } public Double Distance { get; set; } } /// <summary>Collection of Routes</summary> public class Generic_Solution<S, R, V, E> where S : Generic_Solution<S, R, V, E> where R : Generic_Route<R, V, E> where V : Generic_Visit<V, E> where E : Generic_Element<E> { public List<R> Routes { get; set; } public Double Distance { get { return this.Routes.Select(r => r.Distance).Sum(); } } }
TSP Classes:
public class Generic_Tsp_Element<E> : Generic_Element<E> where E : Generic_Tsp_Element<E> { } /// <summary>Visit to a Generic_Element</summary> public class Generic_Tsp_Visit<V, E> : Generic_Visit<V, E> where V : Generic_Tsp_Visit<V, E> where E : Generic_Tsp_Element<E> { public Double Time { get; set; } } /// <summary>Collection of Visits</summary> public class Generic_Tsp_Route<R, V, E> : Generic_Route<R, V, E> where R : Generic_Tsp_Route<R, V, E> where V : Generic_Tsp_Visit<V, E> where E : Generic_Tsp_Element<E> { public Double Time { get { return this.Visits.Select(v => v.Time).Sum(); } } } /// <summary>Collection of Routes</summary> public class Generic_Tsp_Solution<S, R, V, E> : Generic_Solution<S, R, V, E> where S : Generic_Tsp_Solution<S, R, V, E> where R : Generic_Tsp_Route<R, V, E> where V : Generic_Tsp_Visit<V, E> where E : Generic_Tsp_Element<E> { public Double Time { get { return this.Routes.Select(r => r.Time).Sum(); } } } public class Concrete_Tsp_Element : Generic_Tsp_Element<Concrete_Tsp_Element> { } public class Concrete_Tsp_Visit : Generic_Tsp_Visit<Concrete_Tsp_Visit, Concrete_Tsp_Element> { } public class Concrete_Tsp_Route : Generic_Tsp_Route<Concrete_Tsp_Route, Concrete_Tsp_Visit, Concrete_Tsp_Element> { } public class Concrete_Tsp_Solution : Generic_Tsp_Solution<Concrete_Tsp_Solution, Concrete_Tsp_Route, Concrete_Tsp_Visit, Concrete_Tsp_Element> { }
VRP Classes:
public class Generic_Vrp_Element<E> : Generic_Element<E> where E : Generic_Vrp_Element<E> { } /// <summary>Visit to a Generic_Element</summary> public class Generic_Vrp_Visit<V, E> : Generic_Visit<V, E> where V : Generic_Vrp_Visit<V, E> where E : Generic_Vrp_Element<E> { public Double Capacity { get; set; } } /// <summary>Collection of Visits</summary> public class Generic_Vrp_Route<R, V, E> : Generic_Route<R, V, E> where R : Generic_Vrp_Route<R, V, E> where V : Generic_Vrp_Visit<V, E> where E : Generic_Vrp_Element<E> { public Double Capacity { get { return this.Visits.Select(v => v.Capacity).Sum(); } } } /// <summary>Collection of Routes</summary> public class Generic_Vrp_Solution<S, R, V, E> : Generic_Solution<S, R, V, E> where S : Generic_Vrp_Solution<S, R, V, E> where R : Generic_Vrp_Route<R, V, E> where V : Generic_Vrp_Visit<V, E> where E : Generic_Vrp_Element<E> { public Double Capacity { get { return this.Routes.Select(r => r.Capacity).Sum(); } } } public class Concrete_Vrp_Element : Generic_Vrp_Element<Concrete_Vrp_Element> { } public class Concrete_Vrp_Visit : Generic_Vrp_Visit<Concrete_Vrp_Visit, Concrete_Vrp_Element> { } public class Concrete_Vrp_Route : Generic_Vrp_Route<Concrete_Vrp_Route, Concrete_Vrp_Visit, Concrete_Vrp_Element> { } public class Concrete_Vrp_Solution : Generic_Vrp_Solution<Concrete_Vrp_Solution, Concrete_Vrp_Route, Concrete_Vrp_Visit, Concrete_Vrp_Element> { }
The end result is not general generic classes that can be used as follows:
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<Concrete_Tsp_Visit>(new[] { v }); r.Distance = 2.1; var s = new Concrete_Tsp_Solution(); s.Routes = new List<Concrete_Tsp_Route>(new[] { r }); Console.WriteLine(s.Distance); Console.WriteLine(s.Time); Console.ReadLine();
Enjoy it! Enjoy it!