【问题标题】: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 解决了(不,我不知道我在说什么 :))?

【问题讨论】:

    标签: .net-3.5 inheritance interface c#-3.0


    【解决方案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();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-13
      相关资源
      最近更新 更多