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

本文关键字:工具 三元 表达式 一种 分解 | 更新日期: 2023-09-27 18:22:05

与我合作的当前项目的前几位开发人员似乎决定创建一些可工作但无法管理的代码。

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

有人知道有一个免费的工具,独立的或作为VS2008的插件,可以分解三元表达式吗?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;

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

代码的含义实际上比看上去简单得多。继续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 ";
}
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;
                        }
                    }
                }
            }
        }

CodeRush Xpress(免费)可以做到这一点以及更多。请参见此处。

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

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语句,直到不再需要这个怪物为止。我不能保证这就是原作者对逻辑的想象,但我可以保证它在所有可能的情况下都是相同的。

我使用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];

如果我不得不面对这样的情况,我会用它来调查Roslyn,看看它能提供什么帮助。我认为为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