Я борюсь с некоторыми общими проблемами с ограничениями при попытке реализовать библиотеку, которая позволяет наследовать, и надеюсь, что кто-то может помочь.
Я пытаюсь создать библиотеку классов, в которой есть 3 разновидности, каждое из которых строится поверх другого. Мне показалось, что это прекрасная возможность использовать Дженерики, так как я не могу делать то, что хочу, через чистое наследование. Код ниже (это должно быть вставлено прямо в VS) с некоторыми пояснениями после этого:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Test
{
#region Base Classes
public class GenericElement { }
/// <summary>Visit to a GenericElement</summary>
public class Generic_Visit<E> where E : GenericElement
{
public E Element { get; set; }
}
/// <summary>Collection of Visits</summary>
public class Generic_Route<V, E>
where V : Generic_Visit<E>
where E : GenericElement
{
public List<V> Visits { get; set; }
public Double Distance { get; set; }
}
/// <summary>Collection of Routes</summary>
public class Generic_Solution<R, V, E>
where R : Generic_Route<V, E>
where V : Generic_Visit<E>
where E : GenericElement
{
public List<R> Routes { get; set; }
public Double Distance
{
get
{
return this.Routes.Select(r => r.Distance).Sum();
}
}
}
#endregion
#region TSP Classes
public class Concrete_TSPNode : GenericElement { }
public abstract class Generic_TSPVisit<E> : Generic_Visit<E>
where E : Concrete_TSPNode
{
public Double Time { get; set; }
}
public abstract class Generic_TSPRoute<V, E> : Generic_Route<V, E>
where V : Concrete_TSPVisit
where E : Concrete_TSPNode
{
public Double Time
{
get
{
return this.Visits.Select(v => v.Time).Sum();
}
}
}
public abstract class Generic_TSPSolution<R, V, E> : Generic_Solution<R, V, E>
where R : Concrete_TSPRoute
where V : Concrete_TSPVisit
where E : Concrete_TSPNode
{
public Double Time
{
get
{
return this.Routes.Select(r => r.Time).Sum();
}
}
}
public class Concrete_TSPVisit : Generic_TSPVisit<Concrete_TSPNode> { }
public class Concrete_TSPRoute : Generic_TSPRoute<Concrete_TSPVisit, Concrete_TSPNode> { }
public class Concrete_TSPSolution : Generic_TSPSolution<Concrete_TSPRoute, Concrete_TSPVisit, Concrete_TSPNode> { }
#endregion
#region VRP
public class Concrete_VRPNode : Concrete_TSPNode { }
public abstract class Generic_VRPVisit<E> : Generic_TSPVisit<E> where E : Concrete_VRPNode
{
public Double Capacity { get; set; }
}
public abstract class Generic_VRPRoute<V, E> : Generic_TSPRoute<V, E>
where V : Concrete_VRPVisit
where E : Concrete_VRPNode
{
public Double Capacity
{
get
{
return this.Visits.Select(v => v.Capacity).Sum();
}
}
}
public abstract class G_VRPSolution<R, V, E> : Generic_TSPSolution<R, V, E>
where R : Concrete_VRPRoute
where V : Concrete_VRPVisit
where E : Concrete_VRPNode
{
public Double Capacity
{
get
{
return this.Routes.Select(r => r.Capacity).Sum();
}
}
}
public class Concrete_VRPVisit : Generic_VRPVisit<Concrete_VRPNode> { }
public class Concrete_VRPRoute : Generic_VRPRoute<Concrete_VRPVisit, Concrete_VRPNode> { }
public class Concrete_VRPSolution : Generic_TSPSolution<Concrete_VRPRoute, Concrete_VRPVisit, Concrete_VRPNode> { }
#endregion
}
Идея кода заключается в том, что существует набор базовых классов, которые предоставляют свойства с использованием Generics. Это позволяет мне иметь строго типизированные коллекции, например.
Затем на этом этапе строятся 2 из 3 этапов, TSP и VRP, в которых есть 4 конкретных класса (это то, с чем должен взаимодействовать разработчик, использующий библиотеку классов, так как общие ограничения просто сводят с ума) - Элемент, Посещение, Маршрут и Решение.
Есть также некоторые классы с префиксом Generic для TSP и VRP. Они позволяют наследование, которое я хочу, так как оно раскрывает общие типы. Если я не использую их (скажем, Concrete_VRPRoute наследует Concrete_TSPRoute), то мне придется продолжать приводить тип элемента, возвращаемого коллекцией Visits, например, для получения свойства Capacity.
Я вполне уверен, что все типы выстроены правильно , но когда я пытаюсь собрать, я получаю следующие ошибки, и я действительно не знаю, как их решить.
Ошибка 1 Тип «V» не может использоваться как TSP и VRP в примере, которые имеют 4 конкретных класса (это то, с чем разработчик, использующий библиотеку классов, должен взаимодействовать, так как общие ограничения просто сходят с ума) - Element, Visit, Route и Solution.
Есть также некоторые классы имеют префикс Generic для TSP и VRP. Они позволяют наследование, которое я хочу, так как оно раскрывает общие типы. Если я не использую их (скажем, Concrete_VRPRoute наследует Concrete_TSPRoute), то мне придется продолжать приводить тип элемента, возвращаемого коллекцией Visits, например, для получения свойства Capacity.
Я вполне уверен, что все типы выстроены правильно , но когда я пытаюсь собрать, я получаю следующие ошибки, и я действительно не знаю, как их решить.
Ошибка 1 Тип «V» не может использоваться как TSP и VRP в примере, которые имеют 4 конкретных класса (это то, с чем разработчик, использующий библиотеку классов, должен взаимодействовать, так как общие ограничения просто сходят с ума) - Element, Visit, Route и Solution.
Есть также некоторые классы имеют префикс Generic для TSP и VRP. Они позволяют наследование, которое я хочу, так как оно раскрывает общие типы. Если я не использую их (скажем, Concrete_VRPRoute наследует Concrete_TSPRoute), то мне придется продолжать приводить тип элемента, возвращаемого коллекцией Visits, например, для получения свойства Capacity.
Я вполне уверен, что все типы выстроены правильно , но когда я пытаюсь собрать, я получаю следующие ошибки, и я действительно не знаю, как их решить.
Ошибка 1 Тип «V» не может использоваться как Они позволяют наследование, которое я хочу, так как оно раскрывает общие типы. Если я не использую их (скажем, Concrete_VRPRoute наследует Concrete_TSPRoute), то мне придется продолжать приводить тип элемента, возвращаемого коллекцией Visits, например, для получения свойства Capacity.
Я вполне уверен, что все типы выстроены правильно , но когда я пытаюсь собрать, я получаю следующие ошибки, и я действительно не знаю, как их решить.
Ошибка 1 Тип «V» не может использоваться как Они позволяют наследование, которое я хочу, так как оно раскрывает общие типы. Если я не использую их (скажем, Concrete_VRPRoute наследует Concrete_TSPRoute), то мне придется продолжать приводить тип элемента, возвращаемого коллекцией Visits, например, для получения свойства Capacity.
Я вполне уверен, что все типы выстроены правильно , но когда я пытаюсь собрать, я получаю следующие ошибки, и я действительно не знаю, как их решить.
Ошибка 1 Тип «V» не может использоваться как введите параметр 'V' в универсальном типе или метод «Test.Generic_Route». Там нет неявной ссылки преобразование из 'V' в 'Test.Generic_Visit.
Ошибка 2 тип 'V' не может использоваться как тип параметр 'V' в универсальном типе или метод "Test.Generic_Solution". Там нет неявной ссылки преобразование из 'V' в 'Test.Generic_Visit.
Ошибка 3 тип 'R' не может быть использован как тип параметр 'R' в универсальном типе или метод "Test.Generic_Solution". Там нет неявной ссылки преобразование из 'R' в «Test.Generic_Route»
Ошибка 4 Тип «V» нельзя использовать как введите параметр 'V' в универсальном типе или метод 'Test.Generic_TSPRoute. Там есть нет неявного преобразования ссылок из «V» для «Test.Concrete_TSPVisit».
Ошибка 5 Тип «V» нельзя использовать как введите параметр 'V' в универсальном типе или метод 'Test.Generic_TSPSolution. Там нет неявной ссылки преобразование из 'V' в 'Test.Concrete_TSPVisit.
Ошибка 6 тип 'R' не может быть использован как тип параметр 'R' в универсальном типе или метод 'Test.Generic_TSPSolution. Там нет неявной ссылки преобразование из 'R' в 'Test.Concrete_TSPRoute.
Ошибка 7 тип "Test.Concrete_VRPVisit" не может использоваться в качестве параметра типа «V» в универсальный тип или метод 'Test.Generic_TSPSolution. Там нет неявной ссылки преобразование из 'Test.Concrete_VRPVisit' для 'Test.Concrete_TSPVisit.
Ошибка 8 тип "Test.Concrete_VRPRoute" не может использоваться в качестве параметра типа «R» в универсальный тип или метод 'Test.Generic_TSPSolution. Там нет неявной ссылки преобразование из "Test.Concrete_VRPRoute" для 'Test.Concrete_TSPRoute'. 'Test.Concrete_TSPRoute'.