我有几个汽车工厂:

宏达工厂、美塞德斯工厂、丰田工厂

所有这些工厂都有Create()种方法:

Honda Create(HondaParts parts);
Mercedes Create(MercedesParts parts);
Toyota Create(ToyotaParts parts);

所有返回类型执行ICar,所有零件执行ICarParts.

我有一个高于这一切的类,当给定工厂类型和ICarParts时,它只想在工厂上调用Create(),而不需要在类型上使用if/else/if/else语句.

我创建了一个ICarFactory,并给它一个界面:

ICar Create(ICarParts parts)

但后来我陷入了困境,因为当然每个工厂都有不同的签名,即使所有参数都符合ICarParts类型.有没有办法实现我的目标?

推荐答案

使用泛型

abstract class CarFactory<TParts> where TParts : ICarParts 
{
    public abstract ICar Create(TParts parts);
}

class HondaFactory : CarFactory<HondaParts>
{
    public override ICar Create(HondaParts parts)
    {
        ...
    }
}

... other factories

但和往常一样,泛型也有局限性.E、 例如,您无法创建列表<;工厂<&燃气轮机&燃气轮机;包含不同类型的工厂.不同类型的工厂不兼容分配.

在某些时候,您仍然需要if/else/if/else语句来获得正确的工厂.非泛型弱类型方法ICar Create(ICarParts parts)允许更多"动态"场景.

由于C#9.0(我认为是.NET 5.0运行时),您可以使用covariant return types:

    public override Honda Create(HondaParts parts)
    {
        ...
    }

假设public class Honda : ICar.


一种更复杂的方法结合了非泛型和泛型接口.在更动态但弱类型的场景中,针对非泛型接口编程,在其他情况下,针对泛型接口编程:

public interface ICarFactory
{
    ICar Create(ICarParts parts);
}

public interface ICarFactory<in TParts> : ICarFactory
    where TParts : ICarParts
{
    ICar Create(TParts parts);
}

abstract class CarFactory<TParts> : ICarFactory<TParts>
    where TParts : ICarParts
{
    ICar ICarFactory.Create(ICarParts parts) => Create((TParts)parts);

    public abstract ICar Create(TParts parts);
}

注意,非泛型实现是显式完成的,因此只有在直接针对ICarFactory接口编程时才可见.现在,您可以创建如下工厂词典:

var factories = new Dictionary<string, ICarFactory> {
    ["Honda"] = new HondaFactory(),
    ["Mercedes"] = new MercedesFactory(),
    ["Toyota"] = new ToyotaFactory(),
};

现在,您有责任提供正确类型的零件:

string carType = "Toyota";
ICarFactory factory = factories[carType];
ICar car = factory.Create(parts); // Not type safe!

Csharp相关问答推荐

默认的PSHost实现是什么(用于RunspacePool)?

在C# 11之前, struct 中的每个字段都必须显式分配?不能繁殖

为什么xslWriter不总是按照xslWriterSet中指定的格式格式化该文档?

在命令行中使用时安装,但在单击时不会安装

Microsoft. SQLServer. Types(106.1000.6)在try 从用户定义的类型检索值时引发异常

为什么Blazor值在更改后没有立即呈现?

System.Text.Json数据化的C#类映射

无法解析数据库上下文的服务

Polly使用泛型重试和重试包装函数

AsNoTrackingWithIdentitySolutions()似乎不起作用?

Azure DEVOPS找不到定制的Nuget包

为什么我的表单在绑定到对象时提交空值?

如何在用户在线时限制令牌生成?

DateTime ToString()未以指定格式打印

正在try 从Blazor中的API读取JSON

在使用StringBuilder时,如何根据 colored颜色 设置为richTextBox中的特定行着色?

为什么Docker中没有转发该端口?

Postgres ENUM类型在第一次运行时对Dapper不可见

为什么在使用JsonDerivedType序列化泛型时缺少$type?

在C#/ASP.NET Core 7中,什么可能导致POST请求作为GET请求发送