一种可以分解三元表达式的工具

时间:2012-02-01 19:10:29

标签: c# visual-studio-2008

我正在使用的当前项目的先前开发人员似乎决定创建一些有效且无法管理的代码。

在整个代码中,我发现了多条件三元表达式。翻译和重写/重构它们会变得很头疼。

是否有人知道可以分解三元表达式的免费工具,独立或作为VS 2008的加载项? CodeRush在这个项目上没有预算。如果需要,我会继续重新编码,但我想在这里有一点希望。

以下是此问题的一个示例:

sNoteType = objSelection.Items[1].Selected ? 
    objSelection.Items[0].Selected ? 
    objSelection.Items[3].Selected ? 
    objSelection.Items[4].Selected ? 
    objSelection.Items[5].Selected ? 
    objSelection.Items[2].Selected ? 
    string.Empty + "OV " :
    string.Empty + "EV " : 
    objSelection.Items[2].Selected ? 
    string.Empty + "OV " :
    string.Empty + "LT " : 
    objSelection.Items[5].Selected ? 
    objSelection.Items[2].Selected ?
    string.Empty + "OV " : 
    string.Empty + "EV " : 
    objSelection.Items[2].Selected ? 
    string.Empty + "OV " : 
    string.Empty + "BA " : 
    objSelection.Items[4].Selected ? 
    objSelection.Items[5].Selected ? 
    objSelection.Items[2].Selected ? 
    string.Empty + "OV " : 
    string.Empty + "EV " : 
    objSelection.Items[2].Selected ? 
    string.Empty + "OV " : 
    string.Empty + "LT " : 
    objSelection.Items[5].Selected ? 
    objSelection.Items[2].Selected ? 
    string.Empty + "OV " : 
    string.Empty + "EV " : 
    objSelection.Items[2].Selected ? 
    string.Empty + "OV " : 
    string.Empty + "LS " : 
    objSelection.Items[3].Selected ? 
    objSelection.Items[4].Selected ? 
    objSelection.Items[5].Selected ? 
    objSelection.Items[2].Selected ? 
    string.Empty + "OV " : 
    string.Empty + "EV " : 
    objSelection.Items[2].Selected ? 
    string.Empty + "OV " : 
    string.Empty + "LT " : 
    objSelection.Items[5].Selected ? 
    objSelection.Items[2].Selected ? 
    string.Empty + "OV " : 
    string.Empty + "EV " : 
    objSelection.Items[2].Selected ? 
    string.Empty + "OV " : 
    string.Empty + "BA " : 
    objSelection.Items[4].Selected ? 
    objSelection.Items[5].Selected ? 
    objSelection.Items[2].Selected ? 
    string.Empty + "OV " : 
    string.Empty + "EV " : 
    objSelection.Items[2].Selected ? 
    string.Empty + "OV " : 
    string.Empty + "LT " : 
    objSelection.Items[5].Selected ? 
    objSelection.Items[2].Selected ? 
    string.Empty + "OV " : 
    string.Empty + "EV " : 
    objSelection.Items[2].Selected ? 
    string.Empty + "OV " : 
    string.Empty + "FD " : 
    objSelection.Items[0].Selected ? 
    objSelection.Items[3].Selected ? 
    objSelection.Items[4].Selected ? 
    objSelection.Items[5].Selected ? 
    objSelection.Items[2].Selected ? 
    string.Empty + "OV " : 
    string.Empty + "EV " : 
    objSelection.Items[2].Selected ? 
    string.Empty + "OV " : 
    string.Empty + "LT " : 
    objSelection.Items[5].Selected ? 
    objSelection.Items[2].Selected ? 
    string.Empty + "OV " : 
    string.Empty + "EV " : 
    objSelection.Items[2].Selected ? 
    string.Empty + "OV " : 
    string.Empty + "BA " : 
    objSelection.Items[4].Selected ? 
    objSelection.Items[5].Selected ? 
    objSelection.Items[2].Selected ? 
    string.Empty + "OV " : 
    string.Empty + "EV " : 
    objSelection.Items[2].Selected ? 
    string.Empty + "OV " : 
    string.Empty + "LT " : 
    objSelection.Items[5].Selected ? 
    objSelection.Items[2].Selected ? 
    string.Empty + "OV " : 
    string.Empty + "EV " : 
    objSelection.Items[2].Selected ? 
    string.Empty + "OV " : 
    string.Empty + "LS " : 
    objSelection.Items[3].Selected ? 
    objSelection.Items[4].Selected ? 
    objSelection.Items[5].Selected ? 
    objSelection.Items[2].Selected ? 
    string.Empty + "OV " : 
    string.Empty + "EV " : 
    objSelection.Items[2].Selected ? 
    string.Empty + "OV " : 
    string.Empty + "LT " : 
    objSelection.Items[5].Selected ? 
    objSelection.Items[2].Selected ? 
    string.Empty + "OV " : 
    string.Empty + "EV " : 
    objSelection.Items[2].Selected ? 
    string.Empty + "OV " : 
    string.Empty + "BA " : 
    objSelection.Items[4].Selected ? 
    objSelection.Items[5].Selected ? 
    objSelection.Items[2].Selected ? 
    string.Empty + "OV " : 
    string.Empty + "EV " : 
    objSelection.Items[2].Selected ? 
    string.Empty + "OV " : 
    string.Empty + "LT " : 
    objSelection.Items[5].Selected ? 
    objSelection.Items[2].Selected ? 
    string.Empty + "OV " : 
    string.Empty + "EV " : 
    objSelection.Items[2].Selected ? 
    string.Empty + "OV " : 
    string.Empty;

6 个答案:

答案 0 :(得分:11)

代码的含义实际上比它看起来简单得多。继续使用ReSharper,我发现了以下内容:

string sNoteType;
var items = objSelection.Items;

var item0Selected = items[0].Selected;
string item3NotSelectedValue;
if (items[1].Selected)
{
    item3NotSelectedValue = item0Selected ? "LS " : "FD ";
}
else
{
    item3NotSelectedValue = item0Selected ? "LS " : string.Empty;
}

if (items[2].Selected)
{
    sNoteType = "OV ";
}
else
{
    if (items[5].Selected)
    {
        sNoteType = "EV ";
    }
    else
    {
        if (items[4].Selected)
        {
            sNoteType = "LT ";
        }
        else
        {
            if (items[3].Selected)
            {
                sNoteType = "BA ";
            }
            else
            {
                sNoteType = item3NotSelectedValue;
            }
        }
    }
}

由于Jon完成了所有艰苦的工作,这里的编辑我认为将其归结为本质。显然,你想尽快在这个代码周围进行测试 - 因为我无法想象在解码这个怪物时不会犯错误,而自动重构只能让你到目前为止(不是很好,从样本的外观来看)放在这里):

var items = objSelection.Items;
string sNoteType = string.Empty;    
if (items[0].Selected && items[1].Selected) {
    sNoteType = "LS ";
} else if (items[1].Selected) {
    sNoteType = "FD ";
} else if (items[2].Selected) {
    sNoteType = "OV ";
} else if (items[3].Selected) {
    sNoteType = "BA ";    
} else if (items[4].Selected) {
    sNoteType = "LT ";
} else if (items[5].Selected) {
    sNoteType = "EV ";
}

答案 1 :(得分:8)

ReSharper可以将三元转换为if / else。

我实际上通过ReSharper运行它,输出同样可怕。祝你在重构方面好运。

if (objSelection.Items[1].Selected)
            if (objSelection.Items[0].Selected)
                if (objSelection.Items[3].Selected)
                    if (objSelection.Items[4].Selected)
                        if (objSelection.Items[5].Selected)
                            if (objSelection.Items[2].Selected) sNoteType = string.Empty + "OV ";
                            else sNoteType = string.Empty + "EV ";
                        else
                        {
                            if (objSelection.Items[2].Selected) sNoteType = string.Empty + "OV ";
                            else sNoteType = string.Empty + "LT ";
                        }
                    else
                    {
                        if (objSelection.Items[5].Selected)
                            if (objSelection.Items[2].Selected) sNoteType = string.Empty + "OV ";
                            else sNoteType = string.Empty + "EV ";
                        else
                        {
                            if (objSelection.Items[2].Selected) sNoteType = string.Empty + "OV ";
                            else sNoteType = string.Empty + "BA ";
                        }
                    }
                else
                {
                    if (objSelection.Items[4].Selected)
                        if (objSelection.Items[5].Selected)
                            if (objSelection.Items[2].Selected) sNoteType = string.Empty + "OV ";
                            else sNoteType = string.Empty + "EV ";
                        else
                        {
                            if (objSelection.Items[2].Selected) sNoteType = string.Empty + "OV ";
                            else sNoteType = string.Empty + "LT ";
                        }
                    else
                    {
                        if (objSelection.Items[5].Selected)
                            if (objSelection.Items[2].Selected) sNoteType = string.Empty + "OV ";
                            else sNoteType = string.Empty + "EV ";
                        else
                        {
                            if (objSelection.Items[2].Selected) sNoteType = string.Empty + "OV ";
                            else sNoteType = string.Empty + "LS ";
                        }
                    }
                }
            else
            {
                if (objSelection.Items[3].Selected)
                    if (objSelection.Items[4].Selected)
                        if (objSelection.Items[5].Selected)
                            if (objSelection.Items[2].Selected) sNoteType = string.Empty + "OV ";
                            else sNoteType = string.Empty + "EV ";
                        else
                        {
                            if (objSelection.Items[2].Selected) sNoteType = string.Empty + "OV ";
                            else sNoteType = string.Empty + "LT ";
                        }
                    else
                    {
                        if (objSelection.Items[5].Selected)
                            if (objSelection.Items[2].Selected) sNoteType = string.Empty + "OV ";
                            else sNoteType = string.Empty + "EV ";
                        else
                        {
                            if (objSelection.Items[2].Selected) sNoteType = string.Empty + "OV ";
                            else sNoteType = string.Empty + "BA ";
                        }
                    }
                else
                {
                    if (objSelection.Items[4].Selected)
                        if (objSelection.Items[5].Selected)
                            if (objSelection.Items[2].Selected) sNoteType = string.Empty + "OV ";
                            else sNoteType = string.Empty + "EV ";
                        else
                        {
                            if (objSelection.Items[2].Selected) sNoteType = string.Empty + "OV ";
                            else sNoteType = string.Empty + "LT ";
                        }
                    else
                    {
                        if (objSelection.Items[5].Selected)
                            if (objSelection.Items[2].Selected) sNoteType = string.Empty + "OV ";
                            else sNoteType = string.Empty + "EV ";
                        else
                        {
                            if (objSelection.Items[2].Selected) sNoteType = string.Empty + "OV ";
                            else sNoteType = string.Empty + "FD ";
                        }
                    }
                }
            }
        else
        {
            if (objSelection.Items[0].Selected)
                if (objSelection.Items[3].Selected)
                    if (objSelection.Items[4].Selected)
                        if (objSelection.Items[5].Selected)
                            if (objSelection.Items[2].Selected) sNoteType = string.Empty + "OV ";
                            else sNoteType = string.Empty + "EV ";
                        else
                        {
                            if (objSelection.Items[2].Selected) sNoteType = string.Empty + "OV ";
                            else sNoteType = string.Empty + "LT ";
                        }
                    else
                    {
                        if (objSelection.Items[5].Selected)
                            if (objSelection.Items[2].Selected) sNoteType = string.Empty + "OV ";
                            else sNoteType = string.Empty + "EV ";
                        else
                        {
                            if (objSelection.Items[2].Selected) sNoteType = string.Empty + "OV ";
                            else sNoteType = string.Empty + "BA ";
                        }
                    }
                else
                {
                    if (objSelection.Items[4].Selected)
                        if (objSelection.Items[5].Selected)
                            if (objSelection.Items[2].Selected) sNoteType = string.Empty + "OV ";
                            else sNoteType = string.Empty + "EV ";
                        else
                        {
                            if (objSelection.Items[2].Selected) sNoteType = string.Empty + "OV ";
                            else sNoteType = string.Empty + "LT ";
                        }
                    else
                    {
                        if (objSelection.Items[5].Selected)
                            if (objSelection.Items[2].Selected) sNoteType = string.Empty + "OV ";
                            else sNoteType = string.Empty + "EV ";
                        else
                        {
                            if (objSelection.Items[2].Selected) sNoteType = string.Empty + "OV ";
                            else sNoteType = string.Empty + "LS ";
                        }
                    }
                }
            else
            {
                if (objSelection.Items[3].Selected)
                    if (objSelection.Items[4].Selected)
                        if (objSelection.Items[5].Selected)
                            if (objSelection.Items[2].Selected) sNoteType = string.Empty + "OV ";
                            else sNoteType = string.Empty + "EV ";
                        else
                        {
                            if (objSelection.Items[2].Selected) sNoteType = string.Empty + "OV ";
                            else sNoteType = string.Empty + "LT ";
                        }
                    else
                    {
                        if (objSelection.Items[5].Selected)
                            if (objSelection.Items[2].Selected) sNoteType = string.Empty + "OV ";
                            else sNoteType = string.Empty + "EV ";
                        else
                        {
                            if (objSelection.Items[2].Selected) sNoteType = string.Empty + "OV ";
                            else sNoteType = string.Empty + "BA ";
                        }
                    }
                else
                {
                    if (objSelection.Items[4].Selected)
                        if (objSelection.Items[5].Selected)
                            if (objSelection.Items[2].Selected) sNoteType = string.Empty + "OV ";
                            else sNoteType = string.Empty + "EV ";
                        else
                        {
                            if (objSelection.Items[2].Selected) sNoteType = string.Empty + "OV ";
                            else sNoteType = string.Empty + "LT ";
                        }
                    else
                    {
                        if (objSelection.Items[5].Selected)
                            if (objSelection.Items[2].Selected) sNoteType = string.Empty + "OV ";
                            else sNoteType = string.Empty + "EV ";
                        else
                        {
                            if (objSelection.Items[2].Selected) sNoteType = string.Empty + "OV ";
                            else sNoteType = string.Empty;
                        }
                    }
                }
            }
        }

答案 2 :(得分:5)

CodeRush Xpress(免费)可以做到这一点以及更多。请参阅here

答案 3 :(得分:5)

此代码应该与原始怪物的行为相同:

string sNoteType;
if (objSelection.Items[2].Selected)
{
    sNoteType = "OV ";
}
else if (objSelection.Items[5].Selected)
{
    sNoteType = "EV ";
}
else if (objSelection.Items[4].Selected)
{
    sNoteType = "LT ";
}
else if (objSelection.Items[3].Selected)
{
    sNoteType = "BA ";
}
else if (objSelection.Items[0].Selected)
{
    sNoteType = "LS ";
}
else if (objSelection.Items[1].Selected)
{
    sNoteType = "FD ";
}
else
{
    sNoteType = string.Empty;
}

为了达到这个目的,我开始假设无论代码目前做什么都是正确的。然后我编写了一个脚本来生成64个测试用例 - 每个测试用例对应一个真值的组合。想象一下这个:

[TestCase("EV ", "000001")]
[TestCase("LT ", "000010")]
[TestCase("EV ", "000011")]
[TestCase("BA ", "000100")]
[TestCase("EV ", "000101")]

然后,我逐一观察模式并逐一添加if语句,直到根本不再需要怪物为止。我不能保证这是原作者想象逻辑的方式,但我可以保证它在所有可能的情况下都表现相同。

答案 4 :(得分:3)

我使用CodeRush Xpress为您转换了

if (objSelection.Items[1].Selected)
    if (objSelection.Items[0].Selected)
        if (objSelection.Items[3].Selected)
            if (objSelection.Items[4].Selected)
                if (objSelection.Items[5].Selected)
                    if (objSelection.Items[2].Selected)
                        sNoteType = string.Empty + "OV ";
                    else
                        sNoteType = string.Empty + "EV ";
                else
                    if (objSelection.Items[2].Selected)
                        sNoteType = string.Empty + "OV ";
                    else
                        sNoteType = string.Empty + "LT ";
            else
                if (objSelection.Items[5].Selected)
                    if (objSelection.Items[2].Selected)
                        sNoteType = string.Empty + "OV ";
                    else
                        sNoteType = string.Empty + "EV ";
                else
                    if (objSelection.Items[2].Selected)
                        sNoteType = string.Empty + "OV ";
                    else
                        sNoteType = string.Empty + "BA ";
        else
            if (objSelection.Items[4].Selected)
                if (objSelection.Items[5].Selected)
                    if (objSelection.Items[2].Selected)
                        sNoteType = string.Empty + "OV ";
                    else
                        sNoteType = string.Empty + "EV ";
                else
                    if (objSelection.Items[2].Selected)
                        sNoteType = string.Empty + "OV ";
                    else
                        sNoteType = string.Empty + "LT ";
            else
                if (objSelection.Items[5].Selected)
                    if (objSelection.Items[2].Selected)
                        sNoteType = string.Empty + "OV ";
                    else
                        sNoteType = string.Empty + "EV ";
                else
                    if (objSelection.Items[2].Selected)
                        sNoteType = string.Empty + "OV ";
                    else
                        sNoteType = string.Empty + "LS ";
    else
        if (objSelection.Items[3].Selected)
            if (objSelection.Items[4].Selected)
                if (objSelection.Items[5].Selected)
                    if (objSelection.Items[2].Selected)
                        sNoteType = string.Empty + "OV ";
                    else
                        sNoteType = string.Empty + "EV ";
                else
                    if (objSelection.Items[2].Selected)
                        sNoteType = string.Empty + "OV ";
                    else
                        sNoteType = string.Empty + "LT ";
            else
                if (objSelection.Items[5].Selected)
                    if (objSelection.Items[2].Selected)
                        sNoteType = string.Empty + "OV ";
                    else
                        sNoteType = string.Empty + "EV ";
                else
                    if (objSelection.Items[2].Selected)
                        sNoteType = string.Empty + "OV ";
                    else
                        sNoteType = string.Empty + "BA ";
        else
            if (objSelection.Items[4].Selected)
                if (objSelection.Items[5].Selected)
                    if (objSelection.Items[2].Selected)
                        sNoteType = string.Empty + "OV ";
                    else
                        sNoteType = string.Empty + "EV ";
                else
                    if (objSelection.Items[2].Selected)
                        sNoteType = string.Empty + "OV ";
                    else
                        sNoteType = string.Empty + "LT ";
            else
                if (objSelection.Items[5].Selected)
                    if (objSelection.Items[2].Selected)
                        sNoteType = string.Empty + "OV ";
                    else
                        sNoteType = string.Empty + "EV ";
                else
                    if (objSelection.Items[2].Selected)
                        sNoteType = string.Empty + "OV ";
                    else
                        sNoteType = string.Empty + "FD ";
else
    if (objSelection.Items[0].Selected)
        if (objSelection.Items[3].Selected)
            if (objSelection.Items[4].Selected)
                if (objSelection.Items[5].Selected)
                    if (objSelection.Items[2].Selected)
                        sNoteType = string.Empty + "OV ";
                    else
                        sNoteType = string.Empty + "EV ";
                else
                    if (objSelection.Items[2].Selected)
                        sNoteType = string.Empty + "OV ";
                    else
                        sNoteType = string.Empty + "LT ";
            else
                if (objSelection.Items[5].Selected)
                    if (objSelection.Items[2].Selected)
                        sNoteType = string.Empty + "OV ";
                    else
                        sNoteType = string.Empty + "EV ";
                else
                    if (objSelection.Items[2].Selected)
                        sNoteType = string.Empty + "OV ";
                    else
                        sNoteType = string.Empty + "BA ";
        else
            if (objSelection.Items[4].Selected)
                if (objSelection.Items[5].Selected)
                    if (objSelection.Items[2].Selected)
                        sNoteType = string.Empty + "OV ";
                    else
                        sNoteType = string.Empty + "EV ";
                else
                    if (objSelection.Items[2].Selected)
                        sNoteType = string.Empty + "OV ";
                    else
                        sNoteType = string.Empty + "LT ";
            else
                if (objSelection.Items[5].Selected)
                    if (objSelection.Items[2].Selected)
                        sNoteType = string.Empty + "OV ";
                    else
                        sNoteType = string.Empty + "EV ";
                else
                    if (objSelection.Items[2].Selected)
                        sNoteType = string.Empty + "OV ";
                    else
                        sNoteType = string.Empty + "LS ";
    else
        if (objSelection.Items[3].Selected)
            if (objSelection.Items[4].Selected)
                if (objSelection.Items[5].Selected)
                    if (objSelection.Items[2].Selected)
                        sNoteType = string.Empty + "OV ";
                    else
                        sNoteType = string.Empty + "EV ";
                else
                    if (objSelection.Items[2].Selected)
                        sNoteType = string.Empty + "OV ";
                    else
                        sNoteType = string.Empty + "LT ";
            else
                if (objSelection.Items[5].Selected)
                    if (objSelection.Items[2].Selected)
                        sNoteType = string.Empty + "OV ";
                    else
                        sNoteType = string.Empty + "EV ";
                else
                    if (objSelection.Items[2].Selected)
                        sNoteType = string.Empty + "OV ";
                    else
                        sNoteType = string.Empty + "BA ";
        else
            if (objSelection.Items[4].Selected)
                if (objSelection.Items[5].Selected)
                    if (objSelection.Items[2].Selected)
                        sNoteType = string.Empty + "OV ";
                    else
                        sNoteType = string.Empty + "EV ";
                else
                    if (objSelection.Items[2].Selected)
                        sNoteType = string.Empty + "OV ";
                    else
                        sNoteType = string.Empty + "LT ";
            else
                if (objSelection.Items[5].Selected)
                    if (objSelection.Items[2].Selected)
                        sNoteType = string.Empty + "OV ";
                    else
                        sNoteType = string.Empty + "EV ";
                else
                    if (objSelection.Items[2].Selected)
                        sNoteType = string.Empty + "OV ";
                    else
                        sNoteType = string.Empty;

但是,这仍然非常难看。我建议你使用六维真值表

string[,,,,,] table = new string[2,2,2,2,2,2];
table[0, 0, 0, 0, 0, 0] = "AA";
table[0, 0, 0, 0, 0, 1] = "BB";
table[0, 0, 0, 0, 1, 0] = "CC";
table[0, 0, 0, 0, 1, 1] = "DD";
...

然后可以像这样查询

string sNoteType = table[
    objSelection.Items[0].Selected ? 1 : 0,
    objSelection.Items[1].Selected ? 1 : 0,
    objSelection.Items[2].Selected ? 1 : 0,
    objSelection.Items[3].Selected ? 1 : 0,
    objSelection.Items[4].Selected ? 1 : 0,
    objSelection.Items[5].Selected ? 1 : 0];

答案 5 :(得分:1)

如果我不得不面对这样的情况,我会用它来调查罗斯林,看看它是如何起作用的。我认为为VS开发一个插件,重构你选择的三元表达式,将适合“周末”项目。

http://blog.filipekberg.se/2011/10/23/exploring-how-to-write-a-code-analyzer-with-roslyn/ http://blogs.msdn.com/b/csharpfaq/archive/2011/11/03/using-the-roslyn-syntax-api.aspx