C#泛型和多态:一个矛盾?

Nic*_*arr 18 c# generics polymorphism

我只想确认一下我对C#中的Generics的理解.这已经出现在我使用的几个代码库中,其中使用通用基类来创建类型安全的派生实例.我正在谈论的一个非常简单的例子,

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

public class DeriveFrom :SomeClass<string>
{
    public override void SomeMethod()
    {
        base.SomeMethod();
    }
}
Run Code Online (Sandbox Code Playgroud)

当我想以多态方式使用派生实例时,问题出现了.

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

看来,一旦将Generic引入继承层次结构或接口,就不能再以多态方式使用该类族,除非它本身就是内部的.真的吗?

eld*_*rge 13

据我所知,使用代码不需要泛型类的细节(即,它不依赖于什么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();
}
Run Code Online (Sandbox Code Playgroud)

现在,子类SomeClass<T>可以在不同的Ts 上以不同的方式运行,但消耗代码不会改变.

  • 我认为这是最好的解决方案。我们只扩展客户关心的接口,并将泛型隐藏在幕后。 (2认同)

Mat*_*ley 9

我认为你误解了仿制药的观点.泛型允许您概括需要类型的类,但不特别关心它是什么类型.例如,a List<string>是一个字符串列表,但会List是什么?有一个没有任何列表是一个相当无用的概念.

每个专用类(即List<string>)都是它自己的不同类型,编译器将其视为这样.有可能获得泛型类型(typeof(List<>)例如),但在大多数情况下它是无用的,你肯定无法创建它的实例.


Man*_*ani 5

我更喜欢使用抽象类作为所有泛型类型的基础。

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(); }            
}
Run Code Online (Sandbox Code Playgroud)