派生类型不能隐式转换为基接口

Posted

技术标签:

【中文标题】派生类型不能隐式转换为基接口【英文标题】:Derived type cannot be implicitly converted to base interface 【发布时间】:2011-05-07 04:15:08 【问题描述】:
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 上添加一个隐式运算符,但不允许在接口之间转换..

这是否通过 c#4 中的 co/contra varience 解决了(不,我不知道我在说什么 :))?

【问题讨论】:

【参考方案1】:

你是对的。由于 Co/Contravariance,它不起作用。它应该在 C# 4 中工作(我没有测试它,因为我从来不需要这样的东西:P)。

可以在此处找到有关其工作原理的详细说明:Link

【讨论】:

它在 C# 4 中无法开箱即用。IRepo 接口需要使用协方差修饰符进行修改:out【参考方案2】:

你的直觉是对的。这是一个协方差问题。你看,IRepo&lt;IModel&gt;IRepo&lt;MyModel&gt; 是不一样的。

要允许协变类型,您可以使用 C# 4 中的 out 修饰符修复它:

interface IRepo<out T> where T: IModel 

如果您还没有使用 C# 4,则需要加强使用:

IRepo<MyModel> repo = new Repo();

【讨论】:

以上是关于派生类型不能隐式转换为基接口的主要内容,如果未能解决你的问题,请参考以下文章

C#类型转换总结

在 .NET 中使用隐式转换替代多重继承

三元运算符隐式转换为基类

类型转换

C# 类型转换

static_cast显示完成隐式转换