如何避免类型约束的传播?

发布于 2025-01-25 13:49:56 字数 1214 浏览 6 评论 0原文

在基本用例中,我要处理不同的序列化格式,并根据配置格式(通过DI)使用某个工厂。但是,我认为我在这里遇到了一个更普遍的问题,因此我简化了以下用例。

假设我有一个具有通用方法的简单接口:

public interface IProducerFactory
{
    public IProducer<T> CreateProducer<T>();
}

现在我有一个具体实现producterfactorya,效果很好。即使buildera来自外部库,我也可以轻松地创建实例化iproducer&lt; t&gt;

public class ProducerFactoryA : IProducerFactory
{
    public IProducer<T> CreateProducer<T>()
    {
        // some configuration ...
        return new BuilderA<T>().Build();
    }
}

for product> producterfactoryb,我需要使用外部库BuilderB。但是,builderB具有类型约束,这需要我将它们添加到接口iproDucerFactory以及我想使用的地方的任何地方:

public class ProducerFactoryB : IProducerFactory
{
    public IProducer<T> CreateProducer<T>()
        where T : ISomeConstraint, new()
    {
        // some configuration ...
        return new BuilderB<T>().Build();
    }
}

我的问题是,我如何避免这样的情况?显然,我不希望isomemeconstraint来自外部库是我界面的一部分,并在整个代码库中传播此类型。此外,它也会破坏producerfactorya

有没有办法检查这些约束以满足编译器而不将其添加到方法/接口级别的情况下?

In the underlying use case I'm dealing with different serialization formats and depending on the configured format (via DI) a certain factory is used. However, I think I run into a more general problem here, therefore I simplified the following use case.

Suppose I have a simple interface with a generic method:

public interface IProducerFactory
{
    public IProducer<T> CreateProducer<T>();
}

Now I have a concrete implementation ProducerFactoryA, which works just fine. Even though BuilderA comes from an external library, I can easily create an instantiation implementing IProducer<T>:

public class ProducerFactoryA : IProducerFactory
{
    public IProducer<T> CreateProducer<T>()
    {
        // some configuration ...
        return new BuilderA<T>().Build();
    }
}

For ProducerFactoryB, I need to use the external library BuilderB. However, BuilderB has type constraints, which would require me to add them to the interface IProducerFactory and basically everywhere where I want to use it:

public class ProducerFactoryB : IProducerFactory
{
    public IProducer<T> CreateProducer<T>()
        where T : ISomeConstraint, new()
    {
        // some configuration ...
        return new BuilderB<T>().Build();
    }
}

My question is, how can I avoid such a situation? I clearly don't want ISomeConstraint which comes from an external library to be part of my interface and propagate this type throughout my codebase. Furthermore, it would also break ProducerFactoryA.

Is there a way to check these constraints to satisfy the compiler without adding them on the method/interface level?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

辞慾 2025-02-01 13:49:56

iProducerFactory保证任何实现都可以生成任何类型的对象,而无需限制。因此,如果您想要限制,则需要传播它们或摆脱它们。

另一种选择是将通用类型声明为接口的一部分:

public interface IProducerFactory<T>
{
    public IProducer<T> CreateProducer();
}

public class ProducerFactoryB : IProducerFactory<ISomeConstraint>
{
    public IProducer<ISomeConstraint> CreateProducer()
    {
        ...
    }
}

这是一个弱的承诺,即,如果您以某种方式获得了特定类型的生产商工厂,则可以创建该类型的生产商。您还可以混合模式,并具有一个可以为任何类型创建生产商的接口,并且只能创建特定类型。

The IProducerFactory makes a promise that any implementation can produce any kind of object, without restrictions. So if you want restrictions you would need to propagate them or get rid of them.

An alternative would be to declare the generic type as part of the interface:

public interface IProducerFactory<T>
{
    public IProducer<T> CreateProducer();
}

public class ProducerFactoryB : IProducerFactory<ISomeConstraint>
{
    public IProducer<ISomeConstraint> CreateProducer()
    {
        ...
    }
}

This makes a much weaker promise, i.e. if you somehow get a producer factory for a specific type, it can create producers of that type. You could also mix the patterns, and have one interface that can create producers for any type, and one that can only create specific types.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文