- >启动调试模式
- >到达if(calculate)
行
- >将箭头拖到下一行{
- >到达string sValue = "ABC123";
- >抛出异常Object reference not set to an instance of an object.
但是,如果我设置calculate = true并且不要拖动箭头并继续使用F10,则根本没有例外。你可以在代码中看到5例抛出异常和不抛出异常的情况。当我在if之前定义sValue时,没有例外。
你能解释为什么在这种情况下抛出异常吗?
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApplication1
{
class Program
{
public static List<SaleLineItem> SaleItems = new List<SaleLineItem>();
static void Main(string[] args)
{
SaleItems.Add(new SaleLineItem { ItemId = "ABC123", NetAmount = 2 });
SaleItems.Add(new SaleLineItem { ItemId = "ABC123", NetAmount = 3 });
try
{
bool calculate = false;
// string sValue = "ABC123";
if (calculate)
{
string sValue = "ABC123";
decimal total = 0;
#region Exception
total = SaleItems.Where(t => t.ItemId != sValue).Count();
// total = SaleItems.Where(t => t.ItemId != sValue).Sum(t => t.NetAmountWithTax);
// var newSaleItems = SaleItems.FirstOrDefault(t => t.ItemId != sValue);
#endregion
#region No Exception
// string newValue = sValue;
// var newSaleItems = SaleItems.FirstOrDefault();
#endregion
}
}
catch (Exception ex)
{
throw ex;
}
}
}
[Serializable]
public class SaleLineItem
{
public string ItemId { get; set; }
public decimal NetAmount { get; set; }
}
}
答案 0 :(得分:2)
我可能已经找到了发生这种情况的原因。
首先,我提醒你的代码,看看它是什么需要得到这个异常并最终结束:
List<string> SaleItems = new List<string>();
var test = false;
if(test)
{
var sValue = "ABC123";
SaleItems.Count(t => t != sValue);
}
这会产生完全相同的错误,如您所述。
所以我的猜测是这可能是优化某些东西的编译器的问题,所以我看一下这段代码产生的中间语言(IL)。以下是我认为有趣的部分:(注意:以//开头的行只是可视化的注释,注释所属代码的哪一部分)
//000013:
//000014: if(test)
IL_0009: ldloc.1
IL_000a: stloc.2
//000015: {
//000016: var sValue = "ABC123";
//000017:
//000018: SaleItems.Count(t => t != sValue);
//000019: }
//000020: }
//000021: }
//000022: }
IL_000b: ldloc.2
IL_000c: brfalse.s IL_0034
IL_000e: newobj instance void TestConsoleApplciation_delete_.Program/'<>c__DisplayClass0_0'::.ctor()
IL_0013: stloc.3
//000015: {
IL_0014: nop
//000016: var sValue = "ABC123";
IL_0015: ldloc.3
IL_0016: ldstr "ABC123"
断点设置在第14行的if(test)
,在IL中以IL_0009:
开头的行。
现在,如果将调试器拖到下一行(第15行),它将在内部跳转到行IL_0014:
并从那里继续,因此跳过它们之间的行。
现在的问题是,在ldloc.3
行执行的下一个命令是IL_0015:
(忽略nop命令,它什么都不做),这个命令试图加载存储在的变量行IL_0013:
但该命令未执行,因此它会抛出NullReferenceException
,因为无法加载。
注意:我现在不知道这是否是抛出异常的真正原因,但我认为这是一个非常合理的猜测。