Pet*_*ter 4 c# generics open-generics
我试图有一个List开放的泛型类型。是否可能有类似的东西:
public class MessageProcessor
{
private IDictionary<Type, IMessageHandler<>> _messageHandlers
= new Dictionary<Type, IMessageHandler<>>();
public void AddHandler<TMessage>(IMessageHandler<TMessage> handler)
{
var messageType = typeof(TMessage);
// Add to dictionary here
}
public void Handle<TMessage>(TMessage message)
{
// Call the correct handler here.
}
}
Run Code Online (Sandbox Code Playgroud)
IMessageHandler 应该有一个强类型方法:
public void Handle(TMessage message) {}
Run Code Online (Sandbox Code Playgroud)
我的实际示例有些复杂,所以我希望在这里正确地简化了它。
事实是,我对每个处理程序的泛型类型不感兴趣。我只需要他们都在一个地方,我可以很容易地找到正确的处理程序,如果我可以在一个地方得到他们。
专用词典将以消息的类型(TMessage)作为键。所以我想能够做到:
// ByteArrayHandler implements IMessageHandler<byte[]>
x.AddHandler(new ByteArrayHandler())
// StringHandler implements IMessageHandler<string>
x.AddHandler(new StringHandler())
x.Handle("Some message");
x.Handle(new byte[] { 1, 2, 3} );
Run Code Online (Sandbox Code Playgroud)
并有MessageProcessor正确的电话MessageHandler。
小智 6
每个人都知道扩展方法。但是“扩展字段”呢?当然,不可能用一些新字段来扩展某些对象,但是...您看到过ConditionalWeakTable类吗?使用它,我们可以将一些数据附加/关联到现有对象。很棒的功能是我们不需要从该字典中显式删除项目。对象存储为弱引用,因此当GC收集键时,键值对将自动删除。使用它,我们可以发明这个棘手的解决方案:
public class MessageProcessor
{
private static class MessageHandlerHolder<TMessage>
{
public static readonly ConditionalWeakTable<MessageProcessor, IMessageHandler<TMessage>> MessageHandlers =
new ConditionalWeakTable<MessageProcessor, IMessageHandler<TMessage>>();
}
public void AddHandler<TMessage>(IMessageHandler<TMessage> handler)
{
MessageHandlerHolder<TMessage>.MessageHandlers.Add(this, handler);
}
public void Handle<TMessage>(TMessage message)
{
IMessageHandler<TMessage> handler;
if (!MessageHandlerHolder<TMessage>.MessageHandlers.TryGetValue(this, out handler))
throw new InvalidOperationException("...");
handler.Handle(message);
}
}
Run Code Online (Sandbox Code Playgroud)
因此,所有内容都是强类型和静态类型的,客户端无需显式删除处理程序即可避免内存泄漏。