Как использовать наследование, когда используя общие ограничения

Я борюсь с некоторыми общими проблемами с ограничениями при попытке реализовать библиотеку, которая позволяет наследовать, и надеюсь, что кто-то может помочь.

Я пытаюсь создать библиотеку классов, в которой есть 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'.

7
задан Timwi 2 September 2010 в 12:42
поделиться