开发者

Why is this producing a Null Value Exception?

The exception I get is:

The type initializer for MyNamespace.Program threw an exception

The inner exception says

Message: Value cannot be null. Parameter name: collection

Source: ... HashSet ...

This leads me to believe the error开发者_如何学C is occuring on the line indicated below...

class Program
{
    public static IEnumerable<char> WordCharacters = ExpandCharacterSet("A-Za-z0-9_");
    public static IEnumerable<char> NonWordCharacters = ExpandCharacterSet("^A-Za-z0-9_");
    public static IEnumerable<char> SpaceCharacters = ExpandCharacterSet(" \f\n\r\t\v");
    public static IEnumerable<char> NonSpaceCharacters = ExpandCharacterSet("^ \f\n\r\t\v");
    public static IEnumerable<char> DigitCharacters = ExpandCharacterSet("0-9");
    public static IEnumerable<char> NonDigitCharacters = ExpandCharacterSet("^0-9");
    public static IEnumerable<char> WildCharacters = ExpandCharacterSet("^\n");
    public static IEnumerable<char> AllCharacters = Enumerable.Range(0, 256).Select(Convert.ToChar).Where(c => !char.IsControl(c));

    public static IEnumerable<char> ExpandCharacterSet(string set)
    {
        if (set.Length == 0)
            return "";

        var sb = new StringBuilder();
        int start = 0;
        bool invertSet = false;

        if (set[0] == '[' && set[set.Length - 1] == ']')
            set = set.Substring(1, set.Length - 2);
        if (set[0] == '^')
        {
            invertSet = true;
            set = set.Substring(1);
        }
        set = Regex.Unescape(set);

        foreach (Match m in Regex.Matches(set, ".-.|."))
        {
            if (m.Value.Length == 1)
                sb.Append(m.Value);
            else
            {
                if (m.Value[0] > m.Value[2]) throw new ArgumentException("Invalid character set.");
                for (char c = m.Value[0]; c <= m.Value[2]; ++c)
                    sb.Append(c);
            }
        }

        if (!invertSet) return sb.ToString();

        var A = new HashSet<char>(AllCharacters); // <---- change this to "ABC" and the error goes away
        var B = new HashSet<char>(sb.ToString());
        A.ExceptWith(B);
        return A;
    }

    static void Main(string[] args)
    {
    }
}

But I don't know why. When I print the chars,

Console.WriteLine(string.Concat(AllChars));

It prints every character as expected. So why does HashSet think it's null?


I'm guessing that ExpandCharacterSet is being used to initialize another static field. There's no guarantee on the order in which two static fields will be initialized, and so presuably, it's trying to initialize the other field before it initializes AllChars.

Try moving the assignments into an explicit static constructor, with the correct initialization order.

e.g if your current code has:

public static IEnumerable<char> AllChars = Enumerable.Range(0, 256).Select(Convert.ToChar).Where(c => !char.IsControl(c));
public static IEnumerable<char> Expanded = ExpandCharacterSet(...);

Make it instead:

public static IEnumerable<char> AllChars;
public static IEnumerable<char> Expanded;
static <ClassName> {
    AllChars = Enumerable.Range(0, 256).Select(Convert.ToChar).Where(c => !char.IsControl(c));
    Expanded = ExpandCharacterSet(...);
}


I think, AllChars is being set to null from some other part of your code, because the above two methods seems to be working fine.

Can you provide some more details of implementation.


I'm not getting any except on based on the following two lines of code. Where is the line of code that is throwing the exception?

public static IEnumerable<char> AllChars = Enumerable.Range(0, 256)
                                            .Select(Convert.ToChar)
                                            .Where(c => !char.IsControl(c));

var A = new HashSet<char>(AllChars); 
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜