在调试时,我可以在LINQ中查看导致异常的对象吗?

时间:2016-07-26 08:05:14

标签: c# visual-studio linq debugging exception

假设我有这段代码:

IDictionary<int, int> itemPriceDict = loadItemPriceDictionary();
IList<IRow> dbItems = loadItemsFromDatabase();

IList<ItemDTO> itemDTOs = dbItems
    .Select(dbItem => new ItemDTO()
    {
        Id = dbItem.Id,
        Label = dbItem.Label,
        PriceTag = itemPriceDict[dbItem.Id] // Possible KeyNotFoundException
    })
    .ToList();

当给定的价格标签不存在时,我有时会得到一个KeyNotFound异常 对于给定的dbItem。

现在,在Visual Studio中进行调试并抛出异常时,您可以看到StackTrace,TargetSite向您展示触发它的代码行,但是 是否可以找出导致异常的对象(dbItem)并在Debugger中显示它的数据?例如,在Watch窗口中?

我想:

  1. 要么知道词典中没有哪个键
  2. 或者更好地了解密钥以及在Select
  3. 中处理的dbItem

    但无需添加或修改任何代码。

    P.S。:我知道我可以将代码重写为循环,但我不想。

6 个答案:

答案 0 :(得分:4)

你可以这样写Select

.Select(dbItem => 
    {
        return new ItemDTO()
        {
            Id = dbItem.Id,
            Label = dbItem.Label,
            PriceTag = itemPriceDict[dbItem.Id] // Possible KeyNotFoundException
        })
    }
    .ToList();

这将允许您在选择评估中放置断点。

更好的是,进入Debug菜单,然后选择Exceptions(它位于Visual Studio Edition的Windows子菜单下)。

然后进行设置,以便在KeyNotFoundException或您选择的任何例外情况下中断。

当发生异常时,调试器将自动中断,允许您检查相关对象的状态

答案 1 :(得分:2)

出于调试目的,您可以这样做:

 IList<ItemDTO> itemDTOs = dbItems
            .Select(dbItem => {
                try
                {
                    var value = itemPriceDict[dbItem.Id];
                }
                catch (KeyNotFoundException)
                {//Breakpoint goes here
                }
                // Possible KeyNotFoundException
                new ItemDTO()
                {
                    Id = dbItem.Id,
                    Label = dbItem.Label,
                    PriceTag = itemPriceDict[dbItem.Id] // Possible KeyNotFoundException
                };
            })
            .ToList();

或者直接获取列表,这个:

var missingKeys = dbitems.Where(dbItem => !itemPriceDict.ContainsKey(dbItem.Id)).ToList();

答案 2 :(得分:2)

[免责声明:我在OzCode工作]

你试过OzCode吗? Linq调试支持已添加到EAP,其中一个功能是它可以预测查询是否会抛出异常并显示有问题的项目。

enter image description here

通过这种方式,您无需剖析代码或尝试在头脑中进行调试。

答案 3 :(得分:0)

尝试添加其他语句:

IList<ItemDTO> itemDTOs = dbItems.Where(dbitem => dbitem.itemPriceDict[dbItem.Id] != null)
    .Select(dbItem => new ItemDTO()
    {
        Id = dbItem.Id,
        Label = dbItem.Label,
        PriceTag = itemPriceDict[dbItem.Id] // Possible KeyNotFoundException
    })
    .ToList();

答案 4 :(得分:0)

当字典中没有键时,您将获得KeyNotFoundException异常。保留一个顶部变量,并在每次放入Linq查询时分配密钥。您可以使用try和catch块来装饰代码。

(KeyNotFoundException ex)

    try
    {
        int key;

        Dictionary<int, int> dict = new Dictionary<int, int>()
        {
            {1, 2},
            {2,3}
        };

        var x = (from y in dict
                 select new
                 {
                     value = dict[4]

                 }).ToList();

    }
    catch (KeyNotFoundException ex)
    {
         //key that is not there
    }
    catch (Exception ex)
    {

    }

答案 5 :(得分:0)

事实证明,检查这样的物体是完全可以的。 以下是实际演示代码:

Inspecting variable in LINQ while exception is thrown

此外,在Visual Studio 2015中,可以直接在Watch窗口中发出Lambda表达式,以便在运行引发异常的行之前查询集合。

enter image description here