C# 类型初始值设定项引发异常

C# 类型初始值设定项引发异常,c#,initialization,static-classes,C#,Initialization,Static Classes,此类正在引发异常。它没有显示确切的行号,但听起来好像是在静态构造函数中发生的: static class _selectors { public static string[] order = new[] { "ID", "NAME", "TAG" }; public static Dictionary<string, Regex> match = new Dictionary<string, Regex> { { "ID", new Re

此类正在引发异常。它没有显示确切的行号,但听起来好像是在静态构造函数中发生的:

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中更改这些值?

简单的诊断方法:将所有代码移到普通方法中,并找出以这种方式引发的异常。或者只是在调试器中运行它——当抛出异常时,调试器应该会中断

我怀疑这可能是一个糟糕的正则表达式或类似的东西

就我个人而言,我认为静态构造函数中的逻辑太多了,但这是一个稍微不同的问题。。。请注意,您还依赖于此处初始化的顺序:

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

这在目前是可以保证的,但它非常脆弱。

简单的诊断方法:将所有代码移到普通方法中,并找出以这种方式抛出的异常。或者只是在调试器中运行它——当抛出异常时,调试器应该会中断

我怀疑这可能是一个糟糕的正则表达式或类似的东西

就我个人而言,我认为静态构造函数中的逻辑太多了,但这是一个稍微不同的问题。。。请注意,您还依赖于此处初始化的顺序:

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

这在目前是可以保证的,但它非常脆弱。

如果您查看内部异常,您将看到它的状态

收集被修改;列举 操作可能无法执行

这意味着您正在更改正在循环的集合,这是不允许的

而是将构造函数更改为

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

如果查看内部异常,您将看到它

收集被修改;列举 操作可能无法执行

这意味着您正在更改正在循环的集合,这是不允许的

而是将构造函数更改为

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

您在枚举集合时正在修改它。你不能那样做。快速修复方法是将密钥移动到不同的集合中,并枚举:

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

此外,如果您检查了内部异常,您会发现情况就是这样

在枚举集合时正在修改集合。你不能那样做。快速修复方法是将密钥移动到不同的集合中,并枚举:

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

此外,如果您检查了内部异常,您会发现情况就是这样

还有一个建议。。。复习功课。它可能看起来很挑剔,但骆驼壳的公共字段,以下划线开头的类。。。对于任何.NET开发人员来说,这看起来都是一团糟,在他们的眼里都会给你带来不好的影响。我很难对回调之类的东西了如指掌,你能解释一下你代码中下面这行代码的作用吗:publicstaticdictionarrelative=newdictionary{{+,checkSet,part=>{}@sc_ray他有一个字典,它有一个字符串键和一个值,这个值是一个动作,它同时接受XmlNode类型的哈希集和一个字符串。他正在使用字典类型初始值设定项快捷方式,相当于调用.Add+,checkSet,part=>{};它在字典中添加了一个新的键值对,其中键为+并且值是以下方法的lambda等价物:void EmpyMethodHashSet checkSet,string part{/*nothing*/}@Will:我正在移植一个JavaScript库,猜测是哪一个,我正在尝试维护它们的大多数命名约定,这样我就不会混淆自己。该类以下划线开头,因为我将其视为一个成员变量,而不是一个类—它是一个子类。整件事就像一个大的私人常数。@sc_-ray:再加上威尔所说的。。。我只是还没有填写那个“匿名方法”。课程大约完成了一半;还有很多常数需要填充。我可能会采取不同的方法,因为这有点荒谬。另一个建议。。。复习功课。它可能看起来很挑剔,但骆驼壳的公共字段,以下划线开头的类。。。对于任何.NET开发人员来说,这看起来都是一团糟,在他们的眼里都会给你带来不好的影响。我很难对回调之类的东西了如指掌,你能解释一下你代码中下面这行代码的作用吗:publicstaticdictionarrelative=newdictionary{{+,checkSet,part=>{}@sc_ray他有一个字典,它有一个字符串键和一个值,这个值是一个动作,它同时接受XmlNode类型的哈希集和一个字符串。他正在使用字典类型初始值设定项快捷方式,相当于调用.Add+,checkSet,part=>{};它在字典中添加了一个新的键值对,其中键为+并且值是以下方法的lambda等价物:void EmpyMethodHashSet checkSet,string part{/*nothing*/}@Will:我正在移植一个JavaScript库,猜测是哪一个,我正在尝试维护它们的大多数命名约定,这样我就不会混淆自己。该类以下划线开头,因为我将其视为一个成员变量,而不是一个类—它是一个子类。w
洞的行为就像一个大的私人常数。@sc\u-ray:为了补充威尔所说的。。。我只是还没有填写那个“匿名方法”。课程大约完成了一半;还有很多常数需要填充。我可能会采取另一种方法,因为这有点荒谬;枚举操作不能执行。我想这应该会给我通风报信,但我一定没有把它读清楚。@Mark:以后,如果你有内部异常消息,请将其包含在问题中。我仍然认为应该将一些逻辑移到类型初始值设定项之外:它几乎是jQuery的一个直接端口。。。怪他们编写了奇怪的代码:p不过字典确实很方便,因为我需要用一个变量键访问这些正则表达式;枚举操作不能执行。我想这应该会给我通风报信,但我一定没有把它读清楚。@Mark:以后,如果你有内部异常消息,请将其包含在问题中。我仍然认为应该将一些逻辑移到类型初始值设定项之外:它几乎是jQuery的一个直接端口。。。怪他们编写了奇怪的代码:p不过,字典确实很有用,因为我需要用一个变量键访问那些正则表达式。实际上,如果你列出它,你可以跳过for,只需枚举调用的结果。另外,您在这里调用ToList a crapton,这并不是最好的代码。是的,这是正确的,并且要列出的crapton可以被移动到循环X的外部-实际上,如果您调用它,您可以跳过for,只枚举调用的结果。另外,你在这里调用ToList a crapton,这并不是最好的代码。是的,这是真的,要列出的crap ton可以移动到循环外X-嗯,我确实需要一份match[POS]的副本,然后在c'tor中修改它。。。马克:我可能会把大部分工作重构成一个单独的类中的方法。这意味着您可以轻松地对它们进行单元测试。然后,您可以从静态构造函数中使用它们。好吧,我确实需要一份match[POS]的副本,然后才能在c'tor中修改它。。。马克:我可能会把大部分工作重构成一个单独的类中的方法。这意味着您可以轻松地对它们进行单元测试。然后可以从静态构造函数中潜在地使用它们。