我正在从二进制流解码通信消息.我根据已到达的消息创建不同类型的消息对象.它们都源自基本的CommsMessage类型.一切都很好,花花公子.
在我的代码中,我需要对这些消息做出反应,所以我需要知道它是什么类型的消息.
目前我在做:
void ProcessIncomingMessage(CommsMessage msg) { if (msg is MessageType1) return ProcessMessageType1(msg as MessageType1); if (msg is MessageType2) return ProcessMessageType2(msg as MessageType2); //etc }
我想知道比较这些类型的性能成本是什么,以及我是否应该在基类中包含MessageType属性.然后我可以这样做:
void ProcessIncomingMessage(CommsMessage msg) { switch (msg.MessageType) { case MessageType.Type1: return ProcessMessageType1(msg as MessageType1); case MessageType.Type2: return ProcessMessageType2(msg as MessageType2); //etc } }
是的,这是不成熟的优化,我可能会担心无关紧要的细节,但我是那种喜欢知道幕后发生了什么的编码员,因此想知道两者之间的性能差异.我想我对我的C背景中的类型比较存在偏见,其中RTTI引入了开销,并且只是想知道.Net是否有任何相似之处.
解决方法
你有没有考虑过消除类型演员?
我猜你已经考虑过将虚拟方法放在Message类型本身上会破坏分层抽象(例如,你可能希望将消息处理与消息本身清晰地分开).也许考虑visitor pattern.这将允许您将Message类与Message本身的处理分开.
如果你有这种结构的东西.
abstract class CommsMessage {} class Message1 : CommsMessage {} class Message2 : CommsMessage {}
你可以重构
abstract class CommsMessage { public abstract void Visit(CommsMessageVisitor v); } class Message1 : CommsMessage { public void Visit(CommsMessageVisitor v) { v.Accept(this); } } class Message2 : CommsMessage { public void Visit(CommsMessageVisitor v) { v.Accept(this); } } interface CommsMessageVisitor { void Accept(Message1 msg1); void Accept(Message1 msg2); }
此时,您已经消除了类型转换.您现在可以将代码重写为
void ProcessIncomingMessage(CommsMessage msg) { new MyVisitor().Visit(msg); } class MyVisitor : CommsMessageVisitor { void Accept(Message1 msg1) { ProcessMessageType1(msg1); } void Accept(Message1 msg2) { ProcessMessageType2(msg2); } }
当然可能有理由你不能这样做,但如果可以的话,避免使用类型转换总是更好!