【问题标题】:.NET Adding a range of characters to a list.NET 向列表中添加一系列字符
【发布时间】:2009-08-15 20:10:06
【问题描述】:

我想问一下是否有更优雅的方式来做到这一点:

List<char> unallowed = new List<char>();

for (char c = '\u0000'; c <= '\u0008'; c++) {
    unallowed.Add(c);
}

for (char c = '\u000B'; c <= '\u000C'; c++) {
    unallowed.Add(c);
}

// And so on...

我必须在列表中添加一些连续的 Unicode 字符范围,而我唯一能想到的重构上述代码的方法是创建自己的方法以避免重复输入 for 循环。而且我什至不太确定它是否值得。

【问题讨论】:

  • 也许您的方法不适合您要解决的问题。例如,使用正则表达式匹配事物或检查每个字符是否有 Char.IsControl() 可能更容易。 究竟你想做什么?

标签: c# .net list refactoring


【解决方案1】:

好吧,你可以这样做:

    List<char> chars = new List<char>();
    chars.AddRange(Enumerable.Range(0x0000, 9).Select(i => (char)i));
    chars.AddRange(Enumerable.Range(0x000B, 2).Select(i => (char)i));

但不确定是否值得——尤其是考虑到需要使用“count”而不是“end”。可能更容易编写自己的扩展方法...

static void AddRange(this IList<char> list, char start, char end) {
    for (char c = start; c <= end; c++) {
        list.Add(c);
    }
}
static void Main() {
    List<char> chars = new List<char>();
    chars.AddRange('\u0000', '\u0008');
    chars.AddRange('\u000B', '\u000C');
}

请回复您的评论;扩展方法不是 .NET 3.5 功能。它们是 C# 3.0 功能。因此,只要您将代码集编译为目标 .NET 2.0 / 3.0(视情况而定),客户端是否没有 .NET 3.5 也没关系;但是,您确实需要定义 ExtensionAttribute - 只需几行代码:

namespace System.Runtime.CompilerServices
{
    [AttributeUsage(AttributeTargets.Assembly |
        AttributeTargets.Class | AttributeTargets.Method)]
    public sealed class ExtensionAttribute : Attribute { }
}

或者干脆去下载 LINQBridge 并使用 .NET 2.0 中的所有 LINQ-to-Objects。

【讨论】:

  • @Marc:不错的选择。只想指出这是 .Net 3.5 的功能。对我个人而言,这不是一个好的选择,因为我的许多应用程序必须在 3.5 不一定常见并且请求升级可能很困难的环境(通常是大型企业环境)中运行。
  • "只是想指出这是 .Net 3.5 的一个特性" - 不,它不是;查看更新。
【解决方案2】:

添加一个添加范围的方法可能是最简单的重构,我认为它值得,因为它使范围本身更易于阅读。使用MiscUtilRange 类,您可以执行以下操作:

list.AddRange('\u000b'.To('\u000c').Step(1))

但这仍然不如拥有一个额外的方法(可能是List&lt;char&gt;上的扩展方法?)和写作:

list.AddCharRange('\u000b', '\u000c');

多余的文字可以打一两次电话,但如果您重复多次,您真的希望尽可能多地删除多余的文字,以使有用的数据脱颖而出。很遗憾,集合初始化器没有考虑扩展方法,否则这将是一个非常巧妙的解决方案。

您是否确实需要List&lt;char&gt;,但由于其他限制?这听起来就像你真的想要一个Predicate&lt;char&gt; 来说明一个字符是否被允许 - 这可以通过组合范围等来实现。

【讨论】:

    【解决方案3】:

    将不允许的 Unicode 字符放在从文件或内部资源读取的列表中,而不是在应用程序中硬编码是有意义的。

    【讨论】:

    • 不,C# char 包含 Unicode 字符。 (虽然不确定它如何处理代理和其他 >2 字节字符)
    • 是的,我的错。我在想字节。编辑以反映清醒的 cmets :)
    【解决方案4】:

    这就是我创建 Char 列表的方式(实际上就在昨天)。如果您有很多范围要添加到列表中,您可以通过定义添加到列表中的 AddUnallowed(char from, char to) 等方法使其更容易/重复更少。

    【讨论】:

      【解决方案5】:

      您可以将范围放在一个数组中并循环:

      char[] ranges = {
         '\u0000','\u0008',
         '\u000b','\u000c',
         '0','9',
         'a','z'
      };
      
      for (int i = 0; i < ranges.Length; i++) {
         for (char c = ranges[i++]; c <= ranges[i]; c++) {
            unallowed.Add(c);
         }
      }
      

      【讨论】:

        【解决方案6】:

        正如您已经认识到的那样,您的代码中有一些重复。重复通常是不好的,并且一种方法会使您的代码更具可读性,因此它认为这是值得的。扩展方法呢:

        public static class YourHelper
        {
            public static void AddCharRange(this List<char> list, char first, char last)
            {
                for (char c = first; c <= last; c++)
                {
                    list.Add(c);
                }
            }
        }
        

        然后:

        List<char> unallowed = new List<char>();
        unallowed.AddCharRange('\u0000', '\u0008');
        

        根据您的用例,我最终会将方法命名为“Unallow”而不是“AddCharRange”。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-09-10
          • 2023-02-08
          • 2019-10-11
          相关资源
          最近更新 更多