Производный тип не может быть неявно преобразован в базовый интерфейс - PullRequest
4 голосов
/ 09 ноября 2010
interface IModel {}

class MyModel : IModel {}

interface IRepo<T>
    where T: IModel { }

class Repo : IRepo<MyModel> { }

//EDIT: A smaller example
IRepo<IModel> repo = new Repo(); // Cannot implicitly convert.. An explicit convertion exists. Missing cast?

// Old example:
/*
The type 'Repo' cannot be used as type parameter 'C' in the generic type or method.
'Castle.MicroKernel.Registration.ComponentRegistration<S>.ImplementedBy<C>()'.
==> There is no implicit reference conversion from 'Repo' to 'IRepo<IModel>'.
*/
container.Register(
    Component.For<IRepo<IModel>>()
   .ImplementedBy<Repo>());

Но Repo является производным от IRepo, а MyModel - от IModel.Почему это не работает?

Я попытался добавить неявный оператор в Repo, но не допускается преобразование между интерфейсами.# 4 (Нет, я понятия не имею, о чем говорю :))?

Ответы [ 2 ]

3 голосов
/ 09 ноября 2010

Вы правы.Это не работает из-за Co / Contravariance.Предполагается, что он работает в C # 4 (я не тестировал его, потому что никогда не нуждался в таком: P).

Хорошее объяснение того, как это работает, можно найти здесь: http://blogs.msdn.com/b/csharpfaq/archive/2010/02/16/covariance-and-contravariance-faq.aspx

2 голосов
/ 09 ноября 2010

Ваша интуиция была права. Это вопрос ковариации. Видите ли, IRepo<IModel> и IRepo<MyModel> не совпадают.

Чтобы разрешить ковариантные типы, вы можете исправить это с помощью модификатора out в C # 4:

interface IRepo<out T> where T: IModel {}

Если вы еще не находитесь на C # 4, вам необходимо усилить использование:

IRepo<MyModel> repo = new Repo();
...