Тип инициализатора сгенерировал исключение - PullRequest
1 голос
/ 23 сентября 2010

Этот класс создает исключение. Он не показывает точный номер строки, но звучит так, как будто он встречается в статическом конструкторе:

static class _selectors
{
    public static string[] order = new[] { "ID", "NAME", "TAG" };
    public static Dictionary<string, Regex> match = new Dictionary<string, Regex> {
        { "ID", new Regex(@"#((?:[\w\u00c0-\uFFFF-]|\\.)+)") },
        { "CLASS", new Regex(@"\.((?:[\w\u00c0-\uFFFF-]|\\.)+)") },
        { "NAME", new Regex(@"\[name=['""]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['""]*\]") },
        { "ATTR", new Regex(@"\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['""]*)(.*?)\3|)\s*\]") },
        { "TAG", new Regex(@"^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)") },
        { "CHILD", new Regex(@":(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?") },
        { "POS", new Regex(@":(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)") },
        { "PSEUDO", new Regex(@":((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['""]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?") }
    };
    public static Dictionary<string, Action<HashSet<XmlNode>, string>> relative = new Dictionary<string, Action<HashSet<XmlNode>, string>> {
        { "+", (checkSet, part) => {
        }}
    };
    public static Dictionary<string, Regex> leftMatch = new Dictionary<string, Regex>();
    public static Regex origPOS = match["POS"];

    static _selectors()
    {
        foreach (var type in match.Keys)
        {
            _selectors.match[type] = new Regex(match[type].ToString() + @"(?![^\[]*\])(?![^\(]*\))");
            _selectors.leftMatch[type] = new Regex(@"(^(?:.|\r|\n)*?)" + Regex.Replace(match[type].ToString(), @"\\(\d+)", (m) =>
                @"\" + (m.Index + 1)));
        }
    }
}

Почему я не могу изменить эти значения в c'tor?

Ответы [ 3 ]

3 голосов
/ 23 сентября 2010

Если вы посмотрите внутреннее исключение, вы увидите, что оно сообщает

Коллекция была изменена; перечисление операция может не выполняться.

Это означает, что вы меняете зацикленную коллекцию, что недопустимо.

Скорее измените конструктор на что-то вроде

static _selectors()
{
    List<string> keys = match.Keys.ToList();
    for (int iKey = 0; iKey < keys.Count; iKey++)
    {
        var type = keys[iKey];
        _selectors.match[type] = new Regex(match[type].ToString() + @"(?![^\[]*\])(?![^\(]*\))");
        _selectors.leftMatch[type] = new Regex(@"(^(?:.|\r|\n)*?)" + Regex.Replace(match[type].ToString(), @"\\(\d+)", (m) =>
            @"\" + (m.Index + 1)));
    }
}
1 голос
/ 23 сентября 2010

Вы изменяете коллекцию, перечисляя ее. Вы не можете сделать это. Быстрое решение состоит в том, чтобы переместить ключи в другую коллекцию и перечислить, что:

static _selectors()
{
    foreach (var type in match.Keys.ToArray())
    {

Кроме того, если бы вы проверили внутреннее исключение, вы бы увидели, что это так.

1 голос
/ 23 сентября 2010

Простой диагностический подход: переместите весь этот код в обычные методы и выясните, какое исключение выдается таким образом. Или просто запустите его в отладчике - он должен сломаться при возникновении исключения.

Я подозреваю, что это будет плохое регулярное выражение или что-то в этом роде.

Лично я думаю, что это слишком много логики в статическом конструкторе, но это немного другой вопрос ... Обратите внимание, что вы также полагаетесь на порядок инициализации здесь:

public static Regex origPOS = match["POS"];

То, что - это , на данный момент все будет в порядке, но оно очень хрупкое.

...