[英]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.