繁体   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