C # 4.0: Как узнать, совпадают ли типы ко-вариантно - PullRequest
4 голосов
/ 28 мая 2010

Например, у меня есть

interface ICommand {}
class MovePiece : ICommand {}
class Successful<CMD> where CMD : ICommand {}

и я хочу следующее:

CovariantlyEqual(
  typeof(Successful<ICommand>), 
  typeof(Successful<MovePiece>))
.ShouldEqualTrue()

Обновление Эрик спрашивает ниже, почему я хотел бы проверить такую ​​вещь. Справедливо. Я думаю, что во многих случаях была бы полезна возможность легко проверить это «равенство». Возьмите в качестве примера простой агрегатор событий - вы хотите сказать ему, что вы заинтересованы в подписке на все успешные команды. Между тем, другой компонент может быть заинтересован только в успешном событии MovePiece.

Полагаю, я ошибаюсь, но я подумал, что именно в этом и заключается разница и противоречие. Может быть, равенство - это неправильный термин, но очевидно, что существует какая-то связь между определением типа Successful<MovePiece> и Successful<ICommmand>. Разве в языке нет ничего, что могло бы легко его раскрыть?

1 Ответ

4 голосов
/ 28 мая 2010

Прежде всего, даже если такой метод существовал, в вашем случае он не должен быть равен true по двум причинам: (на самом деле, если вы выполните Success<ICommand> c = new Success<MovePiece>(), он даже не скомпилируется.)

  1. Только общие делегаты или универсальные интерфейсы могут быть помечены как варианты, но не классы
  2. Вам необходимо явно пометить его параметрами in или out.

Сказав это, вот небольшая модификация:

interface ICommand { }
class MovePiece : ICommand { }
interface ISuccessful<out CMD> where CMD : ICommand { }
class Implementation<CMD> : ISuccessful<CMD> where CMD : ICommand { }

Если у вас есть это, вы можете использовать метод IsAssignableFrom() на Type:

bool b = typeof(ISuccessful<ICommand>).IsAssignableFrom(typeof(Implementation<MovePiece>));
Console.WriteLine(b);

Это выдаст true.

...