2013-07-01 2 views
3

Это проблема, которая кажется супер базовой, но я до сих пор не могу найти способ ее очистить. Когда у меня есть простое наследование как B и C наследовать отИзбегайте множества бросков в дереве наследования

A 
    | 
|-----| 
B  C 

Допустим, это интерфейс, как:

public interface A 
{ 
    List<A> Children { get; } 
} 

Мой вопрос: Когда я получил через B.Children я должен бросить его B каждый раз, когда я хочу использовать его особенности. Есть ли способ иметь список детей без объявления детей в листьях дерева наследования?

Прецизионность: ребенок всегда имеет тот же тип, что и его родительский (или подтип). И дерево может пойти глубже. В качестве примера рассмотрим систему пользовательского интерфейса с объектами, контейнерами, элементами управления, ярлыками, в которых класс имеет в качестве детей только объекты одного и того же типа или подтипы.


Вот мой код. У меня есть верхний уровень, как

public interface ITerm 
{ 
    String text { get; } 
} 

Тогда, как предлагают @Damien_The_Unbeliever

public interface ITerm<T> : ITerm where T : ITerm 
{ 
    List<T> Children { get; } 
} 

public interface ITermControl : ITerm<ITermControl> { ... } 

public class TermControl : ITermControl { ... } 

Я начинаю думать, что это бесполезно, чтобы иметь доступ к List<ITerm> ITerm.Children, а также List<ITermControl> ITermControl.Children. Вот что я пытался объяснить.

Благодаря

+4

Имеет ли тип всегда тот же тип, что и сам, как дети? Действительно ли ваша иерархия наследования идет глубже? Думаю, нам понадобится больше контекста. –

ответ

4

Вы могли бы попытаться сделать это:

public interface A<T> where T: A<T> { 
    List<T> Children {get;} 
} 

Какой Эрик Липперт описывает в своей статье Curiouser and Curiouser:

Это C# вариация на то, что называется Curiously Recurring Template Pattern в C++, и я оставлю его своим лучшим пользователям, чтобы объяснить его использование на этом языке. По существу, шаблон в C# является попыткой применять использование CRTP.

И указывает на то, что это на самом деле не соблюдение правильных типов во всем - так, в лучшем случае, это форма документации, а не что-то, что мешает плохим вещам происходит.

+0

Я думал об этом, но тогда мы не можем использовать родительский интерфейс, и наследование теряет немного интереса. –

+0

@ Mr.Pe - хорошо, мы могли бы сделать лучше, если вы сможете удалить часть абстракции от своего вопроса и представить конкретные варианты использования, которые нам нужно встретить. –

+0

@ Mr.Pe, если вы используете интерфейс, это означает, что ваш базовый класс будет абстрактным, ничего не потеряется. Если вы хотите использовать базовые атрибуты, вы должны использовать класс. –

Смежные вопросы