Как T
может быть DBase<T>
?
Нет ограничений, которые не позволяют генерировать общий параметр из себя.Хотя это не совсем понятно с приведенным вами примером.Как насчет Вершины / Вершины ?
Выдержка из Википедии:
![enter image description here](https://i.stack.imgur.com/cweZm.png)
В геометрии,вершина (множественное число: вершины или вершины) - это точка, где встречаются две или более кривых, линий или ребер.Как следствие этого определения, точка, где две линии встречаются, образуя угол, а углы многоугольников и многогранников являются вершинами. 1
Как описать вершину (точка)?
// very simplified example
public class Vertex
{
public int X { get; set; }
public int Y { get; set; }
}
Теперь, как мы можем добавить коллекцию связанных вершин в этот класс, но разрешить только то, что происходит от этого класса?
public class Vertex<TVertex> : Vertex
where TVertex : Vertex<TVertex>
{
public IEnumerable<TVertex> Vertices { get; set; }
}
Это универсальная версияскажем:
public Vertex2
{
public IENumerable<Vertex2> Vertices { get; set; }
}
Однако, когда я наследую от Vertex2, мой Vertices
всегда должен быть IEnumerable<Vertex2>
, и правильный способ разрешить Vertices быть производным классом - это использовать этот тип self- ссылка общая.
Извините, Эрик, я потерял смысл в деталях.Что я получил от рекурсии?
При использовании Vertex2
наши производные типы теряют доступ к другим производным свойствам:
public class MyVertex2: Vertex2
{
public int Id { get; set; }
}
, поэтому
var a = new MyVertex2 {Id = 1 };
var b = new MyVertex2 { Id = 2 };
a.Vertices = new List<Vertex2> { b };
b.Vertices = new List<Vertex2> { a };
// can't access Id because it's a Vertex2 not a MyVertex2
var bId = a.Vertices.First().Id;
Конечновы можете разыграть его, но затем вы разыгрываете его повсюду (это не DRY ) ... а что если это не MyVertex (MullReferencesException или InvalidCastException).
public class MyVertex: Vertex<MyVertex>
{
public int Id { get; set; }
}
var a = new MyVertex {Id = 1 };
var b = new MyVertex { Id = 2 };
a.Vertices = new List<MyVertex > { b };
b.Vertices = new List<MyVertex > { a };
var bId = a.Vertices.First().Id;
// or even
var aId = a.Vertices.First().Vertices.First();
каждыйпри переходе к вершинам мы получаем правильный производный тип, а не базовый класс.