C#处理多个if / else if语句的更好方法

时间:2016-03-24 03:12:27

标签: c# winforms if-statement dictionary switch-statement

我有一个类来处理传入的无线消息并解析它们。根据命令的输出,我需要处理一些UI修改,例如突出显示标签,向文本框添加文本等。我​​使用的第一个选项是:

void IncomingMessageIfStatements(Message msg, Host host)
        {
            byte resp;
            if (ParseMessageOptionOne(msg, out resp))
            {
                // Do some windows form stuff
            }    

            else if (ParseMessageOptionTwo(msg, out resp))
            {
                // Do some windows form stuff
            }

            else if (ParseMessageOptionThree(msg, out resp))
            {
                // Do some windows form stuff
            }
        }

        private bool ParseMessageOptionOne(Message msg, out byte resp)
        {
            throw new NotImplementedException();
        }
        private bool ParseMessageOptionTwo(Message msg, out byte resp)
        {
            throw new NotImplementedException();
        }
        private bool ParseMessageOptionThree(Message msg, out byte resp)
        {
            throw new NotImplementedException();
        }

这样可行,但我会有更多else if语句,它可能会变得丑陋。我看到的另一种方式是:

void IncomingMessageSwitchStatements(Message msg, Host host)
        {
            byte resp = 0;
            byte someByte = 0;
            bool output = false;
            switch (someByte)
            {
                case 1:
                    output = ParseMessageOptionOne(msg, out resp);
                    break;
                case 2:
                    output = ParseMessageOptionTwo(msg, out resp);
                    break;
                case 3:
                    output = ParseMessageOptionThree(msg, out resp);
                    break;
                default:
                    //handle exception here
                    break;
            }

            if (output && resp == 0x01)
            {
                UpdateUiFromHere();
            }
        }

        private void UpdateUiFromHere()
        {
            // handle UI updates here
        }

这看起来更干净,按预期工作。但后来我开始关注Dictionary<byte, Func<bool>>,并认为这可能是解决传入多种情况(可能是20)的更好方法。

对于我应该采取的最佳做法的任何建议,鉴于什么需要?

4 个答案:

答案 0 :(得分:3)

由于您要做的是根据索引编号&#34;使用相同的签名调用方法,您可以使用delegate并将其列在Dictionary中(或者如果索引从List开始,则0以明确您的意图。

public delegate bool ParseMessage(Message msg, out byte resp);

然后使用Dictionary列出它:

Dictionary<byte, ParseMessage> parser = new Dictionary<byte, ParseMessage>(){
    {1, new ParseMessage(ParseMessageOptionOne)},
    {2, new ParseMessage(ParseMessageOptionTwo)},
    {3, new ParseMessage(ParseMessageOptionThree)}
};

或使用List

List<ParseMessage> parser = new List<ParseMessage>(){
    new ParseMessage(ParseMessageOptionOne),
    new ParseMessage(ParseMessageOptionTwo),
    new ParseMessage(ParseMessageOptionThree)
};

并称之为:

bool result = parser[resp](msg, out resp); //dictionary
bool result = parser[resp-1](msg, out resp); //list

答案 1 :(得分:0)

我会将解析移动到里面 Message类本身。

//in your factory
app.factory('dataFactory',function($http){

    factory = {};

    //get data
    factory.getData = function(obj){
        return $http({
            method: 'GET',
            url: 'http://jsonplaceholder.typicode.com/postsn'
        })
    };

    return factory
}); 

//in your controller
app.controller(someCtrl,function($scope,dataFactory){

  dataFactory.getData().then(function(data){
      console.log('This will be your data: ', data)
  })

})

我还会为所有选项制作一个枚举:

Options option = msg.GetOption();

然后编写代码以使用它,但是你需要......

public enum Options {
    One,
    Two,
    None
}

很难推荐更多,因为我不知道if (option == Options.One) // or switch(option) // etc. 做了什么,因为它不需要参考...但这应该是一些值得思考的好东西。

答案 2 :(得分:0)

您还可以更改ParseMessageOptionOne,ParseMessageOptionTwo,ParseMessageOptionThree的方法签名,以返回封装输出,响应的响应对象,并使用Func内置委托来存储方法:

public struct ParseResponse
{
    public bool output;
    public byte response;
}

class ParseOptions
{
    Func<Message, ParseResponse>[] options = null;

    public ParseOptions()
    {
        options = new Func<Message, ParseResponse>[]{
            ParseMessageOptionOne,
            ParseMessageOptionTwo,
            ParseMessageOptionThree
        };
    }

    public void IncomingMessageSwitchStatements(Message msg, Host host)
    {            
        byte someByte = 2;

        var response = options[someByte](msg);

        if (response.output && response.response == 0x01)
        {
            //UpdateUiFromHere();
        }
    }

    private ParseResponse ParseMessageOptionThree(Message msg)
    {
        return new ParseResponse { output = true };
    }

 }

答案 3 :(得分:0)

另一种方法是使用LINQ循环遍历委托方法列表,并在找到true条件后立即短路。

private delegate bool ParseMessageWrapper(Message msg, out byte resp);

void IncomingMessageSwitchStatements(Message msg, Host host)
{
    byte resp = 0;
    bool output = false;

    var parseMethods = new List<ParseMessageWrapper>()
    {
        new ParseMessageWrapper(ParseMessageOptionOne),
        new ParseMessageWrapper(ParseMessageOptionTwo),
        new ParseMessageWrapper(ParseMessageOptionThree)
    };

    output = parseMethods.Any(func => func.Invoke(msg, out resp));

    if (output && resp == 0x01)
    {
        UpdateUiFromHere();
    }
}