如何使 C# Switch 语句使用 IgnoreCase [英] How to make C# Switch Statement use IgnoreCase

查看:8
本文介绍了如何使 C# Switch 语句使用 IgnoreCase的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有一个 switch-case 语句,其中 switch 中的对象是字符串,是否可以进行 ignoreCase 比较?

If I have a switch-case statement where the object in the switch is string, is it possible to do an ignoreCase compare?

例如:

string s = "house";
switch (s)
{
  case "houSe": s = "window";
}

s 会得到值window"吗?如何覆盖 switch-case 语句,以便它使用 ignoreCase 比较字符串?

Will s get the value "window"? How do I override the switch-case statement so it will compare the strings using ignoreCase?

推荐答案

您似乎知道,将两个字符串小写并比较它们与进行忽略大小写比较不同.这有很多原因.例如,Unicode 标准允许以多种方式对带有变音符号的文本进行编码.某些字符在单个代码点中同时包含基本字符和变音符号.这些字符也可以表示为基本字符,后跟一个组合变音字符.这两种表示在所有方面都是相等的,并且 .NET Framework 中的区域性感知字符串比较将正确地将它们识别为相等,无论是 CurrentCulture 还是 InvariantCulture(有或没有 IgnoreCase).另一方面,序数比较会错误地认为它们不相等.

As you seem to be aware, lowercasing two strings and comparing them is not the same as doing an ignore-case comparison. There are lots of reasons for this. For example, the Unicode standard allows text with diacritics to be encoded multiple ways. Some characters includes both the base character and the diacritic in a single code point. These characters may also be represented as the base character followed by a combining diacritic character. These two representations are equal for all purposes, and the culture-aware string comparisons in the .NET Framework will correctly identify them as equal, with either the CurrentCulture or the InvariantCulture (with or without IgnoreCase). An ordinal comparison, on the other hand, will incorrectly regard them as unequal.

不幸的是,switch 除了序数比较之外什么都不做.序数比较适用于某些类型的应用程序,例如用严格定义的代码解析 ASCII 文件,但序数字符串比较对于大多数其他用途是错误的.

Unfortunately, switch doesn't do anything but an ordinal comparison. An ordinal comparison is fine for certain kinds of applications, like parsing an ASCII file with rigidly defined codes, but ordinal string comparison is wrong for most other uses.

我过去为获得正确行为所做的只是模拟了我自己的 switch 语句.有很多方法可以做到这一点.一种方法是创建一个由成对的 case 字符串和委托组成的 List<T>.可以使用适当的字符串比较来搜索列表.找到匹配项后,可以调用关联的委托.

What I have done in the past to get the correct behavior is just mock up my own switch statement. There are lots of ways to do this. One way would be to create a List<T> of pairs of case strings and delegates. The list can be searched using the proper string comparison. When the match is found then the associated delegate may be invoked.

另一种选择是执行明显的 if 语句链.这通常没有听起来那么糟糕,因为结构非常规则.

Another option is to do the obvious chain of if statements. This usually turns out to be not as bad as it sounds, since the structure is very regular.

这样做的好处是,在与字符串进行比较时,模拟您自己的开关功能并没有任何性能损失.系统不会像使用整数一样制作 O(1) 跳转表,因此无论如何它都会一次比较每个字符串.

The great thing about this is that there isn't really any performance penalty in mocking up your own switch functionality when comparing against strings. The system isn't going to make a O(1) jump table the way it can with integers, so it's going to be comparing each string one at a time anyway.

如果要比较的情况很多,并且性能是一个问题,那么上面描述的 List<T> 选项可以替换为排序字典或哈希表.那么性能可能会匹配或超过 switch 语句选项.

If there are many cases to be compared, and performance is an issue, then the List<T> option described above could be replaced with a sorted dictionary or hash table. Then the performance may potentially match or exceed the switch statement option.

以下是代表列表的示例:

Here is an example of the list of delegates:

delegate void CustomSwitchDestination();
List<KeyValuePair<string, CustomSwitchDestination>> customSwitchList;
CustomSwitchDestination defaultSwitchDestination = new CustomSwitchDestination(NoMatchFound);
void CustomSwitch(string value)
{
    foreach (var switchOption in customSwitchList)
        if (switchOption.Key.Equals(value, StringComparison.InvariantCultureIgnoreCase))
        {
            switchOption.Value.Invoke();
            return;
        }
    defaultSwitchDestination.Invoke();
}

当然,您可能希望向 CustomSwitchDestination 委托添加一些标准参数和可能的返回类型.而且你会想取更好的名字!

Of course, you will probably want to add some standard parameters and possibly a return type to the CustomSwitchDestination delegate. And you'll want to make better names!

如果您的每个案例的行为不适合以这种方式委托调用,例如如果需要不同的参数,那么您就会被链式 if 语句所困.我也做过几次.

If the behavior of each of your cases is not amenable to delegate invocation in this manner, such as if differnt parameters are necessary, then you’re stuck with chained if statments. I’ve also done this a few times.

    if (s.Equals("house", StringComparison.InvariantCultureIgnoreCase))
    {
        s = "window";
    }
    else if (s.Equals("business", StringComparison.InvariantCultureIgnoreCase))
    {
        s = "really big window";
    }
    else if (s.Equals("school", StringComparison.InvariantCultureIgnoreCase))
    {
        s = "broken window";
    }

这篇关于如何使 C# Switch 语句使用 IgnoreCase的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆