繁体   English   中英

C#泛型类型中的多态

[英]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);
    }
}

泛型不代表类型推断。 泛型用于允许诸如ListDictionaryTree等容器包含任何类型,而无需强制转换为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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM