【问题标题】:How to implement generic polymorphism in c#?如何在 C# 中实现泛型多态性?
【发布时间】:2012-04-18 14:04:22
【问题描述】:

为避免混淆,我总结了一些代码:

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&lt;ISpecificEntity&gt; 直接转换为IManager&lt;IIdentifier&gt; 是行不通的。

我认为使用协方差可以解决问题,但将 IManager&lt;TIdentifier&gt; 更改为 IManager&lt;in TIdentifier&gt; 也无济于事。

那么,有没有办法将specificManager 转换为IManager&lt;IIdentifier&gt;

谢谢,一切顺利。

【问题讨论】:

标签: c# generics inheritance casting covariance


【解决方案1】:

使用IManager&lt;IIdentifier&gt; 你可以做这样的事情:

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

这将导致您的SpecificEntityManager 中出现异常,因为它只接受ISpecificEntity 类型的参数

更新: 您可以在 Eric Lippert's blog 阅读更多关于 C# 中的协变和逆变的信息

【讨论】:

  • ... 这就是为什么不允许做 OP 想做的事情。 +1
  • 但是ISpecificEntity 实现了IIdentifier。而TIdentifier 中的IManager 仅接受IIdentifier。因此,该行不应该有例外。我错了吗?
  • 嗯。你说的对。我想我必须更改我的汇总代码。它不适合原始代码中的问题。
【解决方案2】:

为什么不:

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

?

【讨论】:

  • 因为SpecificEntity 不是IManager&lt;IIdentifier&gt; 而是IIdentifier
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-12-03
  • 2011-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多