[英]Polymorphism in C# generic types
为什么不能这样使用泛型? 声明通用的开放类型或接口,并为每种具体类型直接声明单独的逻辑:
interface IOpen<T>
{
T A { get; }
}
class Concrete<int> : IOpen<int>
{
public int A => 42;
public string B => "42";
}
interface IWorker<T>
{
void Do(IOpen<T> item);
}
class WorkerInt : IWorker<int>
{
public void Do(Concrete<int> item)
{
Console.WriteLine(item.A);
Console.WriteLine(item.B);
}
}
如何避免上述代码中的限制? 如果我创建类ConcreteInt : IOpen<int>
那么WorkerInt
将不会实现IWorker<T>
。 谢谢。
您不能使用<int>
定义class Concrete<int>
-就像您尝试使用称为int
的新泛型类型覆盖int
的常规定义一样。 但是然后在该类中,您尝试实际返回一个int
。
所以它应该看起来像:
class Concrete : IOpen<int>
{
public int A => 42;
public string B => "42";
}
但是现在类WorkerInt
必须看起来像这样:
class WorkerInt : IWorker<int>
{
public void Do(Concrete item)
{
Console.WriteLine(item.A);
Console.WriteLine(item.B);
}
}
但是IWorker<int>
必须实现void Do(IOpen<T> item)
,即使Concrete
实现了IOpen<T>
您也不能使用void Do(Concrete item)
因为它比void Do(IOpen<T> item)
限制更大void Do(IOpen<T> item)
。
因此,您必须以这种方式定义它:
class WorkerInt : IWorker<int>
{
public void Do(IOpen<int> item)
{
Console.WriteLine(item.A);
//Console.WriteLine(item.B);
}
}
但这使item.B
不再起作用,因为IOpen<int>
没有B
属性。
进行此工作的唯一方法是将IWorker
更改为:
interface IWorker<T, R> where T : IOpen<R>
{
void Do(T item);
}
然后, WorkerInt
可以是这样的:
class WorkerInt : IWorker<Concrete, int>
{
public void Do(Concrete item)
{
Console.WriteLine(item.A);
Console.WriteLine(item.B);
}
}
泛型不代表类型推断。 泛型用于允许诸如List
, Dictionary
, Tree
等容器包含任何类型,而无需强制转换为Object
。 它们使容器在静态方面更坚固。
如果您希望能够将一组有限的类型传递给某种处理器,请使用重载方法。
public void Do(int item) { ... }
public void Do(string item) { ... }
这样,方法签名决定了要使用哪种方法。
另外,如果您尝试制作不同的工作程序对象,则可以使用一组类似的静态重载方法来实例化工作程序并调用Do()
方法。
class WorkerManager {
public static void DoWork(int item) {
var worker = new WorkerInt();
worker.Do(item);
}
public static void DoWork(string item) {
var worker = new WorkerString();
worker.Do(item);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.