如何在c#中实现泛型多态 - 第2部分?
我已经发布this question with a bad sample。如何在c#中实现泛型多态 - 第2部分?
此代码应该更好。
为了避免混淆,我总结了一些代码:
using System.Collections.Generic;
namespace ConsoleApplication1
{
class Program
{
static void Main()
{
IManager<ISpecificEntity> specificManager = new SpecificEntityManager();
IManager<IAntoherSpecificEntity> anotherSpecificManager = new AnotherSpecificEntityManager();
Dictionary<string, IManager<IIdentifier>> managers = new Dictionary<string, IManager<IIdentifier>>();
managers.Add("SpecificManager", (IManager<IIdentifier>)specificManager);
managers.Add("AnotherSpecificManager", (IManager<IIdentifier>)anotherSpecificManager);
foreach (var manager in managers.Values)
{
IIdentifier entity = manager.Container.GetEntity();
}
}
}
internal interface IIdentifier
{
int Id { get; set; }
}
internal interface ISpecificEntity : IIdentifier
{
string SpecificValue { get; set; }
}
internal class SpecificEntity : ISpecificEntity
{
public int Id { get; set; }
public string SpecificValue { get; set; }
}
internal interface IAntoherSpecificEntity : IIdentifier
{
string AnotherSpecificValue { get; set; }
}
internal class AntoherSpecificEntity : IAntoherSpecificEntity
{
public int Id { get; set; }
public string AnotherSpecificValue { get; set; }
}
internal interface IContainer<out TIdentifier> where TIdentifier : IIdentifier
{
TIdentifier GetEntity();
}
internal interface ISpecificContainer : IContainer<ISpecificEntity>
{
}
internal class SpecificContainer : ISpecificContainer
{
public ISpecificEntity GetEntity()
{
return new SpecificEntity { SpecificValue = "SpecificValue" };
}
}
internal interface IAnotherSpecificContainer : IContainer<IAntoherSpecificEntity>
{
}
internal class AnotherSpecificContainer : IAnotherSpecificContainer
{
public IAntoherSpecificEntity GetEntity()
{
return new AntoherSpecificEntity { AnotherSpecificValue = "AnotherSpecificValue" };
}
}
internal interface IManager<TIdentifier> where TIdentifier : IIdentifier
{
IContainer<TIdentifier> Container { get; set; }
}
internal class SpecificEntityManager : IManager<ISpecificEntity>
{
public IContainer<ISpecificEntity> Container { get; set; }
}
internal class AnotherSpecificEntityManager : IManager<IAntoherSpecificEntity>
{
public IContainer<IAntoherSpecificEntity> Container { get; set; }
}
}
当我调试的代码我在第12行
得到一个InvalidCastException在Main()
我知道ISpecificEntity
实现IIdentifier
。 但是显然直接从IManager<ISpecificEntity>
转换成IManager<IIdentifier>
不起作用。
我认为使用协方差可以做到这一点,但将IManager<TIdentifier>
更改为IManager<in TIdentifier>
或IManager<out TIdentifier>
也不起作用。
那么,有没有办法将specificManager
转换成IManager<IIdentifier>
?
谢谢,一切顺利。
首先你会明白泛型的错误。
如果你看Foo它是一个泛型类型。 Foo和Foo是NEW类型,它们不是从List派生的,也没有通过继承来连接类型。 使用泛型创建新类型,它不会派生!
但是你要找的是Covariance and Contravariance。这将允许您创建一种“通用多态性”,但您需要在您的通用定义中指定此类型。因此,它仅适用于开箱即用的极少数框架泛型。
class Program
{
static void Main(string[] args)
{
IManager<IIdentifier> f1 = new C1();
IManager<IIdentifier> f2 = new SpecificEntityManager(); //IManager<ISpecificEntity>
}
}
interface IIdentifier { }
interface ISpecificEntity : IIdentifier { }
interface IManager<out T> { }
class C1 : IManager<IIdentifier> { }
class SpecificEntityManager : IManager<ISpecificEntity> { }
这里是你必须改变:
internal interface IContainer<out TIdentifier> where TIdentifier : IIdentifier
{
TIdentifier GetEntity();
}
internal interface IManager<out TIdentifier> where TIdentifier : IIdentifier
{
IContainer<IIdentifier> Container { get; }
}
internal class SpecificEntityManager : IManager<ISpecificEntity>
{
public IContainer<IIdentifier> Container { get; set; }
}
internal class AnotherSpecificEntityManager : IManager<IAntoherSpecificEntity>
{
public IContainer<IIdentifier> Container { get; set; }
}
难道你不需要一个非泛型IManager IManager <TIdentifier>可以继承。然后IManager <IIdentifer>是一个IManager,可以被铸造?
如果将有IManager将继承的通用“ISuperManager”,我如何访问通用属性Container? – Palama 2012-04-18 15:59:55
不一定。 IManager
应该告诉你哪些主要的线()是有问题的。你能告诉我们吗? – 2012-04-18 15:50:12
可能的重复[如何在c#中实现泛型多态?](http://stackoverflow.com/questions/10211072/how-to-implement-generic-polymorphism-in-c) – 2012-04-18 15:54:40
不要重新发布,编辑和改进你的问题。 – 2012-04-18 15:56:15