C # присвоение производного класса переменной базового класса с помощью обобщений - PullRequest
0 голосов
/ 02 декабря 2011

У меня есть набор классов и интерфейсов, которые имеют относительно простую иерархию, однако наличие вещей наследуется, а затем наличие переменной, которая принимает базовый класс, не работает должным образом. Я думаю, проблема в том, что мои динамические типы ДОЛЖНЫ быть where : class, а не where : IEntity, потому что эти типы используются в функциях, которые я не могу изменить.

public interface IB<X, Y> 
    where X : class, IEntity 
    where Y : class, IEntity
{
    ...
}

public abstract class A
{
    ...
}

public abstract class B<X, Y> : A, IB<X, Y> 
    where X : class, IEntity 
    where Y : class, IEntity
{
    ...
}

public interface IEntity
{
    ...
}

public class Entity1 : IEntity
{
    ...
}

public class Entity2 : IEntity
{
    ...
}

public class C : B<Entity1, Entity2>, IB<Entity1, Entity2>
{
   ...
}

И затем, пытаясь использовать все это в функции ...

C c = new C();
IB<IEntity, IEntity> ib = c;

Не может это безумие или простота.

Как мне заставить это работать?

Ответы [ 2 ]

3 голосов
/ 02 декабря 2011

Ваш интерфейс ковариантно недействителен.То есть

IB<IEntity, IEntity> и IB<Entity1, Entity2> - это не одно и то же.Чтобы исправить это, вы можете использовать ключевое слово out для параметров типа в определении интерфейса

public interface IB<out X, out Y> where X : class where Y : class

В качестве вторичной точки вам необходимо каскадно связать ваши ограничения с классом B

public abstract class B<X, Y> : A, IB<X, Y> where X : class where Y : class

С этими изменениями ваше назначение C в ib является законным.

C c = new C(); 
IB<IEntity, IEntity> ib = c;

(И, как правильно указывает Davy8 в комментариях, эта ковариационная функция интерфейса требует C # 4 +.)

0 голосов
/ 02 декабря 2011

Вам нужно будет изменить определение class B следующим образом:

public abstract class B<X, Y> : A, IB<X, Y> where X : class where Y : class 
{
    ...
}

Ограничения должны быть указаны по всей цепочке наследования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...