Я немного упростил ваш код, чтобы привести его к примеру, показывающему, что пошло не так. Есть несколько шагов.
Вот мое первоначальное упрощение:
public interface IBaseEntity { }
public class MyTable : IBaseEntity { }
public class BaseData<E> where E : IBaseEntity { }
public class MyTableData : BaseData<MyTable> { }
public class BaseBLL<E, D> where E : IBaseEntity where D : BaseData<E> { }
public class MyTableBLL : BaseBLL<MyTable, MyTableData> { }
public abstract class Controller<E, B> where E : IBaseEntity where B : BaseBLL<E, BaseData<E>> { }
public class MyTableController : Controller<MyTable, MyTableBLL> { }
Теперь, на этом этапе, вся часть кода IBaseEntity
не нужна для репликации вашей проблемы, поэтому Я удалил его:
public class BaseData { }
public class MyTableData : BaseData { }
public class BaseBLL<D> where D : BaseData { }
public class MyTableBLL : BaseBLL<MyTableData> { }
public abstract class Controller<B> where B : BaseBLL<BaseData> { }
public class MyTableController : Controller<MyTableBLL> { }
Теперь я сделал несколько хитрых переименований типов:
public class Fruit { }
public class Apple : Fruit { }
public class BowlOf<D> where D : Fruit { }
public class BowlOfApples : BowlOf<Apple> { }
public abstract class Controller<B> where B : BowlOf<Fruit> { }
public class BowlOfApplesController : Controller<BowlOfApples> { }
То, что это показывает, это то, что когда вы определяете Controller<BowlOfApples>
, вы говорите, что BowlOfApples
должен наследоваться от BowlOf<Fruit>
. Но BowlOfApples
наследуется от BowlOf<Apple>
, а не BowlOf<Fruit>
!
Это ограничение должно иметь смысл. Давайте предположим, что BowlOf<T> : List<T>
и у нас есть Banana : Fruit
, затем представьте, что этот код был допустимым:
BowlOf<Apple> apples = new BowlOf<Apple>();
BowlOf<Fruit> fruit = apples; // BOOM!!! imagine if this could be done!
Banana banana = new Banana();
fruit.Add(banana);
У нас есть код, который может добавить Banana
к BowlOf<Apple>
! Этого не может быть Нелегальная вещь - бросить BowlOf<Apple>
в BowlOf<Fruit>
.
Проще говоря, BowlOf<Apple>
НЕ Унаследует от BowlOf<Fruit>
. Это несмотря на Apple
наследование от Fruit
.
Ваш код делает ту же ошибку, когда вы пытаетесь привести BaseBLL<MyTable, MyTableData>
к BaseBLL<MyTable, BaseData<MyTable>>
.
Вы правильно определили в вашем вопросе, что это изменение будет работать:
public abstract class Controller<F, B> where F : Apple where B : BowlOf<F> { }
public class BowlOfApplesController : Controller<Apple, BowlOfApples> { }
Итак, когда вы говорите: «Но я не хочу вводить класс Data, потому что он уже включен в класс BLL». Ну, вы не можете избежать этого.