这是什么操作员," ??"

时间:2017-09-25 18:16:38

标签: c# dll syntax nullreferenceexception

我正在升级项目,最近开始遇到DLL升级版本的问题。我反编译原始的dll并找到以下if语句:

if (fieldConfiguration == null && Context.ContentDatabase != null)
{
    Item obj = Context.ContentDatabase.SelectSingleItem(
        string.Format("//*[@@templateid='{0}' and @@key='{1}']", 
            (object) TemplateIDs.TemplateField, (object) fieldName));
}

然后我反编译了DLL的升级版本,声明如下:

if (fieldConfiguration == null && (Context.ContentDatabase ?? Context.Database) != null)
{
    Item obj = Context.ContentDatabase.SelectSingleItem(
        string.Format("//*[@@templateid='{0}' and @@key='{1}']", 
            (object) TemplateIDs.TemplateField, (object) fieldName));
}

我能够通过dotPeek反编译DLL并使用dotPeek符号服务器功能来逐步完成代码。我可以看到使用升级DLL时代码失败,因为Context.ContentDatabase为null。我不明白的是如何评估双三元运算符。有人可以向我澄清那里发生了什么吗?似乎这个程序集的创建者想要对Context.ContentDatabase进行空检查,但可能犯了一个错误。谢谢你的帮助!

3 个答案:

答案 0 :(得分:2)

好吧,看起来像是一个错误。代码正在查看Context.ContentDatabaseContext.Database是否不是null,然后继续使用前者,即使它是null

代码应如下所示:

var database = Context.ContentDatabase ?? Context.Database;

if (fieldConfiguration == null && database != null)
{
    Item obj = database.SelectSingleItem(
        string.Format("//*[@@templateid='{0}' and @@key='{1}']", 
            (object) TemplateIDs.TemplateField, (object) fieldName));
}

使用null-coalescing运算符将数据库存储在单独的变量中,然后对其进行操作,如果它不是null

因此,您应该联系提供此库的团队并向他们提交错误。

答案 1 :(得分:0)

如果Context.ContentDatabase不为null,则

(Context.ContentDatabase ?? Context.Database)表达式结果为Context.ContentDatabase,否则它将为Context.Database。 null-coalesce运算符是向前简化null检查的一步。

文档:https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-conditional-operator

答案 2 :(得分:0)

假设Context.ContentDatabase和Context.Database是相同的类型。以下代码应该有效。

var contentDatabase = Context.ContentDatabase ?? Context.Database;
if (fieldConfiguration == null && contentDatabase != null)
{
Item obj = contentDatabase.SelectSingleItem(
    string.Format("//*[@@templateid='{0}' and @@key='{1}']", 
        (object) TemplateIDs.TemplateField, (object) fieldName));
}