Проблема с циклической ссылкой generic классов
От: Silentor Украина  
Дата: 26.06.11 17:44
Оценка:
Добрый день (или вечер)!

Пишу некий фреймворк. Там имеются базовые классы парента BaseParent и чайлдов BaseChild. В паренте я хочу иметь список чайлдов, а в чайлде — ссылку на парента. Пишу через generic'и:
public abstract class BaseParent<TChild>
        where TChild : BaseChild<BaseParent<TChild>>
    {
        protected List<TChild> _childs = new List<TChild>();
    }

public abstract class BaseChild<TParent>
        where TParent : BaseParent<BaseChild<TParent>>
    {
        protected TParent _parent;
    }

Компилятор ругается:
The type 'GenericsTest.BaseParent<TChild>' cannot be used as type parameter 'TParent' in the generic type or method 'GenericsTest.BaseChild<TParent>'. There is no implicit reference conversion from 'GenericsTest.BaseParent<TChild>' to 'GenericsTest.BaseParent<GenericsTest.BaseChild<GenericsTest.BaseParent<TChild>>>'.
The type 'GenericsTest.BaseChild<TParent>' cannot be used as type parameter 'TChild' in the generic type or method 'GenericsTest.BaseParent<TChild>'. There is no implicit reference conversion from 'GenericsTest.BaseChild<TParent>' to 'GenericsTest.BaseChild<GenericsTest.BaseParent<GenericsTest.BaseChild<TParent>>>'.

И я его понимаю Но хочется, чтобы клиент мог использовать конструкцию:
public class MyParent : BaseParent<MyChild>
    {}

public class MyChild : BaseChild<MyParent>
    {}

и получать доступ к типизированным чайлдам и паренту.
Можно ли как-то реализовать мой сценарий, или же надо кардинально менять архитектуру? Если менять, то в какую сторону? Разрывать взаимную ссылку и требовать, чтобы клиент ручками приводил, например, ссылку на парента:
public abstract class BaseParent<TChild>
        where TChild : BaseChild
    {
        protected List<TChild> _childs = new List<TChild>();
    }

    public abstract class BaseChild
    {
        protected Object _parent;
    }

    public class MyParent : BaseParent<MyChild>
    { }

    public class MyChild : BaseChild
    {
        private new MyParent _parent { get { return (MyParent)base._parent; } }
    }

Уже голову сломал, размышляя, не хватает опыта работы с генериками Хоть Эрику Липперту пиши :-D
generic генерик циклическая ссылка
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.