更新:创建了一个简单的解决方案
正如埃里克在下面所说的那样,我有点普通的高兴,但它仍然没有真正解决我的问题。我想出了一个更好的解决方案来从我的核心程序集中删除 MassTransit 依赖项。
我已经在下面发布了详细的答案。
原始问题
有没有办法对通用参数施加约束,表明它必须是具体实现的类型?
目前我正在使用进行反射的单元测试以确保所有实现都正确形成,但我希望编译器让它失败。
例子:
抽象基础
// this abstract class extends another generic type that needs to know
// the type of the concrete implementation "TConsumer"
public abstract class ConsumerBase<TMessage,TConsumer> :
Consumes<AssignedMessage<TMessage,TConsumer>>.All
where TMessage : IMessage
where TConsumer : {{The class that's implementing me}}
{
}
应该成功
// this class passes it's own type as a generic arg to it's base
// and it works great!
public class TestConsumer : ConsumerBase<TestMessage, TestConsumer>
{ }
应该失败
// this class passes a different type as a generic arg to its base
// and should FAIL!!! but how?
public class FailConsumer : ConsumerBase<TestMessage, TestConsumer>
{ }
更新:进一步说明
进一步解释我为什么要这样做...
我正在尝试创建一个基于 MassTransit 的抽象(说起来容易做起来难)。公共(public)交通需要消费者实现 Consume
在我的例子中,TMessage 是一个 AssignedMessage
需要使用 AssignedMessage
话虽如此,它仍然没有完全抽象出 MassTransit。它为我提供了一个公共(public)交通下的基类,这在某种程度上隐藏了我正在实现一个 MassTransit 接口(interface)的事实,但它仍然是一个 MassTransit 依赖项。
最佳答案
正如 Lee 正确指出的那样,这个概念在 C# 类型系统中不存在。你可以靠近,但不能完全到达那里。我关于这个主题的文章在这里:
http://blogs.msdn.com/b/ericlippert/archive/2011/02/03/curiouser-and-curiouser.aspx
我建议您患有泛型幸福病,这种疾病会导致开发人员尝试在泛型类型和约束的复杂相互作用中捕获所有业务逻辑,而不管这对类型。
通用类型系统旨在解决“我有一个苹果列表、一个恐龙列表和一个价格列表;我希望所有这些列表共享相同的实现”这一问题。您的类型:
public abstract class ConsumerBase<TMessage,TConsumer> :
Consumes<AssignedMessage<TMessage,TConsumer>>
是对通用类型系统的滥用。假设你问某人“消息的消费者和消费者是什么?”没有患上普遍性幸福病的人会说“消息和消费者的消费者是一种消费消息和消费者的指定消息的消费者”吗?
我的建议是大量简化您的系统。您试图在此处的类型系统中捕获太多内容。
关于c# - 抽象出 MassTransit 依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21945701/