C# 精简switch语句
想知道是否有好的替代方案,它的性能不比我下面介绍的差?real switch语句有其他非英语字符的附加部分 请注意,我希望每行放置多个case语句,但StyleCop不喜欢它,因此将导致我们的发布版本失败C# 精简switch语句,c#,switch-statement,C#,Switch Statement,想知道是否有好的替代方案,它的性能不比我下面介绍的差?real switch语句有其他非英语字符的附加部分 请注意,我希望每行放置多个case语句,但StyleCop不喜欢它,因此将导致我们的发布版本失败 var retVal = String.Empty; switch(valToCheck) { case "é": case "ê": case "è":
var retVal = String.Empty;
switch(valToCheck)
{
case "é":
case "ê":
case "è":
case "ë":
retVal = "e";
break;
case "à":
case "â":
case "ä":
case "å":
retVal = "a";
break;
default:
retVal = "-";
break;
}
首先想到的是一本
字典()
(我更喜欢char而不是string,因为您正在处理char)
首先想到的是一本字典()
(我更喜欢char而不是string,因为您正在处理char)
好吧,从这个转换开始
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;
}
}
}
公共类字符消毒剂
{
私有静态字典characterMappings=新字典();
静态字符消毒剂()
{
字符映射。添加(“e”、“e”);
字符映射。添加(“ê”、“e”);
//...
}
公共静态字符串映射字符(字符串输入)
{
字符串输出;
if(characterMappings.TryGetValue(输入、输出))
{
返回输出;
}
其他的
{
返回输入;
}
}
}
现在,角色映射是数据的一部分,而不是代码的一部分。我已经在这里硬编码了这些值,但现在将映射存储在一个文件中,读入该文件,然后相应地填充字典就足够简单了。通过这种方式,您不仅可以通过将case语句缩减为一位文本文件(代码之外)来大量清理代码,而且还可以在不需要重新编译的情况下对其进行修改。好的,从执行此转换开始
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;
}
}
}
公共类字符消毒剂
{
私有静态字典characterMappings=新字典();
静态字符消毒剂()
{
字符映射。添加(“e”、“e”);
字符映射。添加(“ê”、“e”);
//...
}
公共静态字符串映射字符(字符串输入)
{
字符串输出;
if(characterMappings.TryGetValue(输入、输出))
{
返回输出;
}
其他的
{
返回输入;
}
}
}
现在,角色映射是数据的一部分,而不是代码的一部分。我已经在这里硬编码了这些值,但现在将映射存储在一个文件中,读入该文件,然后相应地填充字典就足够简单了。通过这种方式,您不仅可以通过将case语句缩减为一位文本文件(代码之外)来大量清理代码,还可以在不需要重新编译的情况下对其进行修改。您可以进行小范围检查并查看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';
<>这使得代码有点混乱,取决于所使用的标准,但可能需要考虑的事情。 < p>您可以进行一个小范围检查并查看<强> ASCII值>/P>
假设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';
<>这使得代码有点混乱,取决于所使用的标准,但可能要考虑的事项。 < p>使用<代码>包含< /代码>而不是<代码>开关< /代码> .<
var retVal = String.Empty;
string es = "éêèë";
if (es.Contains(valToCheck)) retVal = "e";
//etc.
使用包含
而不是开关
var retVal = String.Empty;
string es = "éêèë";
if (es.Contains(valToCheck)) retVal = "e";
//etc.
这个答案假定您将把switch语句应用于字符串,而不仅仅是单个字符(尽管这样也可以)
最好的方法似乎是中概述的方法
我将其调整为使用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的using指令代码>
样本输入:
样本输出:
这个答案假定您将把switch语句应用于字符串,而不仅仅是单个字符(尽管这样也可以)
最好的方法似乎是中概述的方法
我将其调整为使用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的using指令代码>
样本输入:
样本输出:
基于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;
//...
}
基于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;
//...
}
出于好奇,为什么默认的“-”
?您可以构建一个查找表(使用可读性最高的方法,这可能会很慢)。查找非常简单,速度也非常快。@LittleBobbyTables:C#根本不支持这一点,IIRC。您可以直接返回结果,而不是设置retval
(假设以后不使用)。@DaveShaw:感谢您的链接。出于好奇,为什么默认的“-”
?您可以构建一个查找表(使用可读性最高的方法,可能会比较慢)。查找非常简单,速度也非常快。@LittleBobbyTables:C#根本不支持这一点,IIRC。您可以直接返回结果,而不是设置retval
(假设以后不使用)@DaveShaw:谢谢你的链接。为了提高性能,请使用TryGetValue而不是ContainsKey。对于编译,请使用字典而不是字典。与其使用==false
,不如使用NOT运算符(!
)@TimCopenhaver要跟进Steve的评论,如果你打电话给ContainsKey,然后打电话给indexer,你会打电话给FindEntry两次。这类似于在真正的字典中查找一个单词是否在那里,如果在那里,关闭字典,打开它再次查找该单词,然后阅读定义。@Steve这就像添加+0
或*1
到数值计算的结尾。这是毫无意义的。而且char retValue='';
可以是char retValue;
为了性能,请使用TryGetValue而不是ContainsKey。对于编译,请使用Dictionary
而不是Dictionary
。而不是==false
您应该