2012-04-18 53 views
5

,以避免混淆我总结了一些代码:如何在c#中实现泛型多态?

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main() 
     { 
      IManager<ISpecificEntity> specificManager = new SpecificEntityManager(); 
      IManager<IIdentifier> manager = (IManager<IIdentifier>) specificManager; 
      manager.DoStuffWith(new SpecificEntity()); 
     } 
    } 

    internal interface IIdentifier 
    { 
    } 

    internal interface ISpecificEntity : IIdentifier 
    { 
    } 

    internal class SpecificEntity : ISpecificEntity 
    { 
    } 

    internal interface IManager<TIdentifier> where TIdentifier : IIdentifier 
    { 
     void DoStuffWith(TIdentifier entity); 
    } 

    internal class SpecificEntityManager : IManager<ISpecificEntity> 
    { 
     public void DoStuffWith(ISpecificEntity specificEntity) 
     { 
     } 
    } 
} 

当我调试的代码我得到了Main()一个InvalidCastException。

我知道ISpecificEntity执行IIdentifier。 但是显然直接从IManager<ISpecificEntity>转换成IManager<IIdentifier>不起作用。

我想与协方差的工作可以做的伎俩,但改变IManager<TIdentifier>IManager<in TIdentifier>也没有帮助。

那么,有没有办法将specificManager转换成IManager<IIdentifier>

谢谢,一切顺利。

+0

请阅读:http://stackoverflow.com/questions/245607/how-is-generic-covariance-contra-variance-implemented-in-c-sharp-4-0 – 2012-04-18 14:09:03

回答

7

随着IManager<IIdentifier>你可以做这样的事情:

IIdentifier entity = new NotSpecificEntity(); 
manager.DoStuffWith(entity); 

这将导致异常,在你SpecificEntityManager,因为它仅接受类型的参数ISpecificEntity

UPDATE: 你可以阅读更多有关协变和逆变在C#在Eric Lippert's blog

+0

...这就是为什么它不是不允许做OP想要做的事情。 +1 – 2012-04-18 14:13:15

+0

@DanielHilgarth究竟:) – 2012-04-18 14:16:30

+0

但'ISpecificEntity'实现'IIdentifier'。 'IManager'中的'TIdentifier'只接受'IIdentifier'。所以,这条线不应该有例外。我错了吗? – Palama 2012-04-18 14:32:03

2

为什么不:

ISpecificEntity bankAccountManager = new SpecificEntity(); 
IManager<IIdentifier> manager = (IManager<IIdentifier>)bankAccountManager; 
manager.DoStuffWith(new SpecificEntity()); 

+0

因为'SpecificEntity'不是'IManager '而是'IIdentifier'。 – Palama 2012-04-18 14:41:10