簡體   English   中英

C#泛型和多態:一個矛盾?

[英]C# Generics and polymorphism: an oxymoron?

我只想確認一下我對C#中的泛型的理解。 這已經出現在我使用的幾個代碼庫中,其中使用通用基類來創建類型安全的派生實例。 我正在談論的一個非常簡單的例子,

public class SomeClass<T>
{
    public virtual void SomeMethod(){ }
}

public class DeriveFrom :SomeClass<string>
{
    public override void SomeMethod()
    {
        base.SomeMethod();
    }
}

當我想以多態方式使用派生實例時,問題出現了。

public class ClientCode
{
    public void DoSomethingClienty()
    {
        Factory factory = new Factory();
        //Doesn't compile because SomeClass needs a type parameter!
        SomeClass someInstance = factory.Create();

        someInstance.SomeMethod();
    }
}

看來,一旦將Generic引入繼承層次結構或接口,就不能再以多態方式使用該類族,除非它本身就是內部的。 真的嗎?

據我所知,使用代碼不需要泛型類的細節(即,它不取決於T是什么)。 那么,為什么不介紹SomeClass<T>將實現的接口,並使用該接口的實例。

例如:

public interface ISome
{
    void SomeMethod();
}

public class SomeClass<T>: ISome
{
    public virtual void SomeMethod(){ }
}

public void DoSomethingClienty()
{
    Factory factory = new Factory();
    ISome someInstance = factory.Create();

    someInstance.SomeMethod();
}

現在, SomeClass<T>子類可以在不同的T s上以不同的方式運行,但消耗代碼不會改變。

我認為你誤解了仿制葯的觀點。 泛型允許您概括需要類型的類,但不特別關心它是什么類型。 例如, List<string>是一個字符串列表,但List是什么? 擁有一個沒有任何列表是一個相當無用的概念。

每個專用類(即List<string> )都是它自己的不同類型 ,編譯器將其視為此類。 可以獲取泛型類型本身(例如typeof(List<>) ),但在大多數情況下它是無用的,你肯定無法創建它的實例。

我更喜歡使用抽象類作為所有泛型類型的基礎。

public abstract class SomeClass 
{
    public abstract void SomeMethod();
}

public class SomeClass<T> : SomeClass
{
    public override void SomeMethod() { }            
}

public class DeriveFrom<String> : SomeClass<String>
{
    public override void SomeMethod() { base.SomeMethod(); }            
}

看來,一旦將Generic引入繼承層次結構或接口,就不能再以多態方式使用該類族

正確,它與這種情況非常相似:

class StringContainer
{
}

class IntContainer
{
}

StringContainer container = new IntContainer(); // fails to compile

但你可以這樣做:

class Container
{
}

class Container<T> : Container
{
}

Container container = new Container<String>(); // OK

我想你要找的是:

SomeClass(of someType) someInstance = factory(of someType).Create();
or maybe
  SomeClass(of someType) someInstance = factory.Create(of someType)();
or
  SomeClass(of someType) someInstance = factory.Create();

可以有一組工廠類來創建不同的泛型類,或者讓工廠使用泛型類型參數來指示它應該創建哪種泛型類型(請注意,在任何一種情況下,type參數都是泛型的類型參數類,而不是泛型類本身)。 也可以有一個工廠,用於返回一種特定形式的泛型類型的實例。

public Class ReflectionReport<T> 
{
    // This class uses Reflection to produce column-based grids for reporting.  
    // However, you need a type in order to know what the columns are. 
}

... so, in another class you have...

public Class ReflectionReportProject {
    ReflectionReport<Thang> thangReport = new ReflectionReport<Thang>(); 
    ReflectionReport<Thong> thongReport = new ReflectionReport<Thong>(); 



    ... some more stuff ...

    // Now, you want to pass off all of the reports to be processed at one time....
    public ReflectionReport<????>[] ProvideReports() 
    {
        return new ReflectionReport<????>[] { thangReport, thongReport } ;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM