.NET将一系列字符添加到列表中

时间:2009-08-15 20:10:06

标签: c# .net list refactoring

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

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循环。我甚至不太确定这是值得的。

6 个答案:

答案 0 :(得分:4)

嗯,你可以这样做:

    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));

不确定它是否值得 - 特别是考虑到需要使用“计数”而不是“结束”。可能更容易编写自己的扩展方法......

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到对象。

答案 1 :(得分:1)

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

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

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

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

对于一两个电话来说,额外的好处是可以接受的,但是如果你多次重复这一点,那么真的想要尽可能多地删除无关的文本,以使其变得有用数据脱颖而出。遗憾的是,集合初始化程序不考虑扩展方法,否则会产生一个非常简洁的解决方案。

由于其他限制,您肯定需要List<char>吗?这个听起来就像你真的希望Predicate<char>说出是否允许一个角色 - 这可以通过组合范围等来实现。

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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

答案 4 :(得分:0)

您可以将范围放在数组中并循环遍历:

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);
   }
}

答案 5 :(得分:0)

在你的代码中有一些重复,正如你已经认识到的那样。重复通常很糟糕,一种方法可以使你的代码更具可读性,因此它认为值得。扩展方法怎么样:

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”。