减少switch语句

时间:2012-07-25 20:16:58

标签: c# switch-statement

想知道是否有更好的替代方案,表现不比我下面的更糟糕?真正的switch语句还有其他非英文字符的部分。

请注意,我希望每行添加多个case语句,但StyleCop不喜欢它,因此会失败我们的发布版本。

        var retVal = String.Empty;
        switch(valToCheck)
        {
            case "é": 
            case "ê": 
            case "è": 
            case "ë":
                retVal = "e";
                break;
            case "à": 
            case "â": 
            case "ä": 
            case "å":
                retVal = "a";
                break;

            default:
                retVal = "-";
                break;
        }

6 个答案:

答案 0 :(得分:4)

首先想到的是Dictionary<char,char>()
(我更喜欢char而不是字符串,因为你正在处理字符)

Dictionary<char,char> dict = new Dictionary<char,char>();
dict.Add('å', 'a');
......

然后你可以删除你的整个开关

char retValue;
char testValue = 'å';
if(dict.TryGetValue(testValue, out retValue) == false)
   retVal = '-';

答案 1 :(得分:1)

好吧,开始做这个转变。

public class CharacterSanitizer
{
    private static Dictionary<string, string> characterMappings = new Dictionary<string, string>();
    static CharacterSanitizer()
    {
        characterMappings.Add("é", "e");
        characterMappings.Add("ê", "e");
        //...
    }

    public static string mapCharacter(string input)
    {
        string output;
        if (characterMappings.TryGetValue(input, out output))
        {
            return output;
        }
        else
        {
            return input;
        }
    }
}

现在,您处于字符映射是数据的一部分而不是代码的位置。我在这里硬编码了这些值,但是在这一点上它很简单,可以将映射存储在一个文件中,读入文件然后相应地填充字典。通过这种方式,您不仅可以通过将case语句减少到一位文本文件(代码之外)来大量清理代码,而且可以修改它而无需重新编译。

答案 2 :(得分:1)

您可以进行小范围检查并查看 ascii

假设InRange(val, min, max)检查数字是否为,是的,在范围内..

if(InRange(System.Convert.ToInt32(valToCheck),232,235))
  return 'e';
else if(InRange(System.Convert.ToInt32(valToCheck),224,229))
  return 'a';

这使得代码有点混乱,并且取决于所使用的标准,但也许需要考虑。

答案 3 :(得分:1)

这个答案假设您要将该switch语句应用于字符串,而不仅仅是单个字符(尽管这也可以)。

最好的方法似乎是this StackOverflow answer中列出的方法。

我改编它使用LINQ:

var chars = from character in valToCheck.Normalize(NormalizationForm.FormD)
            where CharUnicodeInfo.GetUnicodeCategory(character)
                    != UnicodeCategory.NonSpacingMark
            select character;
return string.Join("", chars).Normalize(NormalizationForm.FormC);

您需要System.Globalization;

的使用指令

示例输入:

string valToCheck = "êéÈöü";

示例输出:

eeEou

答案 4 :(得分:1)

基于Michael Kaplan的RemoveDiacritics(),您可以这样做:

static char RemoveDiacritics(char c)
{
    string stFormD = c.ToString().Normalize(NormalizationForm.FormD);
    StringBuilder sb = new StringBuilder();

    for (int ich = 0; ich < stFormD.Length; ich++)
    {
        UnicodeCategory uc = CharUnicodeInfo.GetUnicodeCategory(stFormD[ich]);
        if (uc != UnicodeCategory.NonSpacingMark)
        {
            sb.Append(stFormD[ich]);
        }
    }

    return (sb.ToString()[0]);
}

switch(RemoveDiacritics(valToCheck))
{
    case 'e':
        //...
        break;
    case 'a':
        //...
        break;
        //...
}

或者,甚至可能是:

retval = RemoveDiacritics(valToCheck);

答案 5 :(得分:0)

使用Contains代替switch

var retVal = String.Empty;

string es = "éêèë";
if (es.Contains(valToCheck)) retVal  = "e";
//etc.