C#泛型类型中的多态性

C#泛型类型中的多态性,c#,oop,generics,C#,Oop,Generics,为什么不能像这样使用泛型?直接为每个具体类型声明公共开放类型或接口以及单独的逻辑: 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&

为什么不能像这样使用泛型?直接为每个具体类型声明公共开放类型或接口以及单独的逻辑:

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);
    }
}
interface-IOpen
{
T{get;}
}
混凝土类别:IOpen
{
公共int A=>42;
公共字符串B=>“42”;
}
接口IWorker
{
无效Do(IOpen项);
}
班级工作人员:IWorker
{
公共空间Do(混凝土项目)
{
控制台写入线(A项);
控制台写入线(B项);
}
}

如何避免上述代码中的限制?如果我创建类
ConcreteInt:IOpen
,那么
WorkerInt
将不会实现
IWorker
。谢谢。

泛型不是类型推断的占位符。泛型意味着允许诸如
列表
字典
等容器包含任何类型,而无需在
对象
之间进行转换。它们使容器在静态上更加健壮

如果您希望能够将有限的一组类型传递给某种处理器,那么请使用重载方法

public void Do(int item) { ... }

public void Do(string item) { ... }
这样,方法签名就决定了使用哪个方法

此外,如果您试图创建不同的worker对象,则可以使用一组类似的静态重载方法来实例化worker并调用
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);
    }
}

泛型并不意味着作为类型推断的占位符。泛型意味着允许诸如
列表
字典
等容器包含任何类型,而无需在
对象
之间进行转换。它们使容器在静态上更加健壮

如果您希望能够将有限的一组类型传递给某种处理器,那么请使用重载方法

public void Do(int item) { ... }

public void Do(string item) { ... }
这样,方法签名就决定了使用哪个方法

此外,如果您试图创建不同的worker对象,则可以使用一组类似的静态重载方法来实例化worker并调用
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);
    }
}

你不能用
定义
类混凝土
——就像你试图用一个名为
int
的新泛型类型覆盖
int
的正常定义一样。但是,在类中,您试图实际返回一个
int

所以它应该看起来像:

class Concrete : IOpen<int>
{
    public int A => 42;
    public string B => "42";
}
但是
IWorker
必须实现
void Do(IOpen项)
,即使
Concrete
实现
IOpen
您也不能使用
void Do(Concrete项)
,因为它比
void Do(IOpen项)
更具限制性

所以你必须这样定义它:

class WorkerInt : IWorker<int>
{
    public void Do(IOpen<int> item)
    {
        Console.WriteLine(item.A);
        //Console.WriteLine(item.B);
    }
}
那么
WorkerInt
可以是:

class WorkerInt : IWorker<Concrete, int>
{
    public void Do(Concrete item)
    {
        Console.WriteLine(item.A);
        Console.WriteLine(item.B);
    }
}
class WorkerInt:IWorker
{
公共空间Do(混凝土项目)
{
控制台写入线(A项);
控制台写入线(B项);
}
}

您不能用
定义
类混凝土
——这就像您试图用一个名为
int
的新泛型类型覆盖
int
的正常定义一样。但是,在类中,您试图实际返回一个
int

所以它应该看起来像:

class Concrete : IOpen<int>
{
    public int A => 42;
    public string B => "42";
}
但是
IWorker
必须实现
void Do(IOpen项)
,即使
Concrete
实现
IOpen
您也不能使用
void Do(Concrete项)
,因为它比
void Do(IOpen项)
更具限制性

所以你必须这样定义它:

class WorkerInt : IWorker<int>
{
    public void Do(IOpen<int> item)
    {
        Console.WriteLine(item.A);
        //Console.WriteLine(item.B);
    }
}
那么
WorkerInt
可以是:

class WorkerInt : IWorker<Concrete, int>
{
    public void Do(Concrete item)
    {
        Console.WriteLine(item.A);
        Console.WriteLine(item.B);
    }
}
class WorkerInt:IWorker
{
公共空间Do(混凝土项目)
{
控制台写入线(A项);
控制台写入线(B项);
}
}
界面IWorker,其中T:IOpen
看起来像一个魔术,它在没有严重代码更改的情况下工作。谢谢。
界面IWorker,其中T:IOpen
看起来像一个魔术,它在没有严重代码更改的情况下工作。非常感谢。