我有代码在数据库中选择一些对象,如下所示:
db.ObjectTypes.GroupJoin(db.Terms, t => t.Id, term => term.ObjectTypeId, (t, terms) => new Term()
{
Type = t.Type,
ObjectTypeId = t.Id,
Deadline = ((int?)terms.FirstOrDefault().Deadline ?? 0),
});
问题是,当没有任何对象时,这条线是如何工作的,所以FirstOrDefault()
会返回null
((int?)terms.FirstOrDefault().Deadline ?? 0)
对我来说,这段代码看起来可能会在它实际保存时崩溃。所以我希望在这种情况下得到一个空引用异常。我试图将行改为
(terms.FirstOrDefault()?.Deadline ?? 0)
这样你知道它可以为null,但这在表达式中不起作用。
我知道它有效并且没有例外,因为代码实际上并没有被执行但是已经转换为sql,但是我正在寻找解释为什么它这样做并且不可能在另一种方式?
答案 0 :(得分:0)
嗯,就像提到的 Enigmativity 一样,代码将不会被执行。由于terms
为空,因此不会进行分组,因此不会执行FirstOrDefault()
。
您可以在以下示例中看到它。 (只是一个简单的)
using System;
using System.Collections.Generic;
using System.Linq;
public class static Program {
public static void Main()
{
var terms = new List<Term>();
var result = ((int?)terms.FirstOrDefault().Deadline ?? 0);
Console.WriteLine(result);
var result2 = (terms.FirstOrDefault()?.Deadline ?? 0);
Console.WriteLine(result2);
}
private class Term
{
public int Deadline { get; set; }
}
}
上面的代码将被翻译成以下代码:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
[assembly: AssemblyVersion("0.0.0.0")]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[module: UnverifiableCode]
public class Program
{
private class Term
{
[DebuggerBrowsable(DebuggerBrowsableState.Never), CompilerGenerated]
private int <Deadline>k__BackingField;
public int Deadline
{
[CompilerGenerated]
get
{
return this.<Deadline>k__BackingField;
}
[CompilerGenerated]
set
{
this.<Deadline>k__BackingField = value;
}
}
}
public static void Main()
{
List<C.Term> source = new List<C.Term>();
int? num = new int?(source.FirstOrDefault<C.Term>().Deadline);
int value = num.HasValue ? num.GetValueOrDefault() : 0;
Console.WriteLine(value);
// just added this line for more readability
C.Term expr_3A = source.FirstOrDefault<C.Term>();
int value2 = (expr_3A != null) ? expr_3A.Deadline : 0;
Console.WriteLine(value2);
}
}
您可以看到您提到的行(((int?)terms.FirstOrDefault().Deadline ?? 0)
)会产生NullReferenceException
。 ?.
将避免例外。
您可以尝试here或只使用上面的示例代码创建Console Application
。