C#静态方法和属性:对象引用未设置为对象的实例

3

我正在使用静态方法和属性。当我调用一个静态方法时,会出现NullReferenceException异常。

样例类:

internal class Utils
{
    private static Regex[] _allRegexes = { _regexCategory };
    private static Regex _regexCategory = new Regex(@"(?<name>c(ategory){0,1}):(?<value>([^""\s]+)|("".+""))\s*", RegexOptions.IgnoreCase);

    public static string ExtractKeyWords(string queryString)
    {
        if (string.IsNullOrWhiteSpace(queryString))
            return null;   

        _allRegexes[0];//here: _allRegexes[0]==null throw an exception
    }
}    

原因:

_allRegexes[0]==null

我无法理解为什么会发生这种情况,我认为在调用该方法时应该初始化_allRegexes

有人可以解释一下吗?


3
allRegexes本身不是一个有效的语句...? - Marc Gravell
3个回答

2
静态字段按照声明顺序进行初始化。这意味着当您初始化_allRegexes时,_regexCategorynull
引用自C#语言规范版本4.0-10.5.5.1静态字段初始化:
“类的静态字段变量初始值设定项对应于一系列分配,这些分配按照它们在类声明中出现的文本顺序执行。”
这导致_allRegexes成为一个包含单个null元素的数组,即new Regex[]{null}
这意味着您可以通过将_regexCategory放在类中_allRegexes之前来修复代码。

抱歉,那时有点混乱..哈哈..实际上我回答了同样的问题,但被downvoted了吗? - Anirudha
如果添加一个静态构造函数会怎样? - Scott 混合理论
@Kevin 静态构造函数会在字段初始化后运行。字段的初始化仍将按文本顺序运行。 - CodesInChaos

1

应该是这样的

    private static Regex _regexCategory = new Regex(@"(?<name>c(ategory){0,1}):(?<value>([^""\s]+)|("".+""))\s*", RegexOptions.IgnoreCase);
    private static Regex[] _allRegexes = { _regexCategory };

在你的代码中,IL 将会把 _regexCategory 加载到 _allRegexes 中,但是因为 IL 从未对其进行 初始化,所以它是 NULL
当你使用 new 关键字实例化 _regexCategory 时,它将被 初始化

1

这段代码可以在没有 NRE 的情况下正常工作

internal class Utils
{
    private static Regex _regexCategory = new Regex(
        @"(?<name>c(ategory){0,1}):(?<value>([^""\s]+)|("".+""))\s*", 
        RegexOptions.IgnoreCase);
    private static Regex[] _allRegexes = { _regexCategory };


    public static string ExtractKeyWords(string queryString)
    {
        if (string.IsNullOrWhiteSpace(queryString))
            return null;

        //change it to your needs, I just made it compile
        return _allRegexes[0].Match(queryString).Value;
    }
}    

class Program
{
    static void Main(string[] args)
    {
        string result = Utils.ExtractKeyWords("foo");
    }
}

我相信问题在于参数初始化的顺序。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接