代码之家  ›  专栏  ›  技术社区  ›  simendsjo

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

  •  4
  • simendsjo  · 技术社区  · 14 年前
    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变量解决的吗(不,我不知道我在说什么:)?

    2 回复  |  直到 14 年前
        1
  •  2
  •   Brian Genisio    14 年前

    你的直觉是对的。这是一个协方差问题。你看, IRepo<IModel> IRepo<MyModel> 不一样。

    为了允许协变类型,可以使用 out C 4中的修饰语:

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

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

    IRepo<MyModel> repo = new Repo();
    
        2
  •  3
  •   tucaz    14 年前

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

    关于它如何工作的一个很好的解释可以在这里找到: http://blogs.msdn.com/b/csharpfaq/archive/2010/02/16/covariance-and-contravariance-faq.aspx