避免多次铸造

mr *_*ose 5 c# performance casting quickfix


我有一个接收基类型参数的方法,并根据实际参数类型执行一些预处理.
这是我的代码:


public void OnMessageReceived(QuickFix42.Message message)
{
    if (message is QuickFix42.ExecutionReport)
    {
        ProcessExecutionReport(message as QuickFix42.ExecutionReport);
    }
    else if (message is QuickFix42.AllocationACK)
    {
        ProcessAllocationAck(message as QuickFix42.AllocationACK);
    }
    else if (message is QuickFix42.OrderCancelReject)
    {
        ProcessOrderCancelReject(message as QuickFix42.OrderCancelReject);
    }
    // ...
}
Run Code Online (Sandbox Code Playgroud)

一切正常,但我从Visual Studio得到以下警告:

Warning 760 CA1800 : Microsoft.Performance : 'message', a parameter, is cast to type 'ExecutionReport' multiple times in method 'MessageProcessor.OnMessageReceived(Message)'. Cache the result of the 'as' operator or direct cast in order to eliminate the redundant isint instruction.

避免这些多余演员的最佳方法是什么?

Jul*_*rau 11

不要同时使用isas.您只需使用as并检查结果是否为null:

QuickFix42.ExecutionReport execReport = message as QuickFix42.ExecutionReport
if (execReport != null)
{
  ProcessExecutionReport(execReport);
}
Run Code Online (Sandbox Code Playgroud)


Eni*_*ity 7

鉴于代码的重复结构,您可以通过以下方式清理它:

public void OnMessageReceived(QuickFix42.Message message)
{
    ExecuteOnlyAs<QuickFix42.ExecutionReport>(message, ProcessExecutionReport);
    ExecuteOnlyAs<QuickFix42.AllocationACK>(message, ProcessAllocationAck);
    ExecuteOnlyAs<QuickFix42.OrderCancelReject>(message, ProcessOrderCancelReject);
}

private void ExecuteOnlyAs<T>(QuickFix42.Message message, Action<T> action)
{
    var t = message as T;
    if (t != null)
    {
        action(t);
    }
}
Run Code Online (Sandbox Code Playgroud)

这确实假设类型不相互继承.如果他们这样做,您将需要更改ExecuteOnlyAs以返回bool指示成功并像以前一样执行if语句.


Ani*_*Ani 5

正如其他人发布的那样,单一的as后续null测试将非常有效.我注意到,这似乎是一个QuickFix应用程序.QuickFix提供了一个专门构建的MessageCracker类,我确信它是有效实现的,可以将常规FIX消息"破解"为特定的强类型消息对象,它看起来正是你想要做的.这样做的好处不仅仅是(可能)提高了性能; 代码将更清晰(更少的检查和强制转换,并且每个消息处理代码将自然地移动到适当的处理程序)并且在无效消息面前更加健壮.

编辑:看看MessageCrackerJohn Zwinck提示的源代码,我们认为使用这个类可能会带来更好的性能.

示例:(使您的类继承自MessageCracker)

public void OnMessageReceived(QuickFix42.Message message, SessionID sessionID)
{
  crack (message, sessionID);
}

public override void onMessage(QuickFix42.ExecutionReport message, SessionID sessionID)
{
   ...
}

public override void onMessage(QuickFix42.OrderCancelReject message, SessionID sessionID)
{
   ...
}
Run Code Online (Sandbox Code Playgroud)