C# 调试时,我可以在LINQ中查看导致异常的对象吗?
假设我有以下代码:C# 调试时,我可以在LINQ中查看导致异常的对象吗?,c#,visual-studio,linq,debugging,exception,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,
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();
IDictionary itemPriceDict=loadItemPriceDictionary();
IList dbItems=loadItemsFromDatabase();
IList itemDTOs=dbItems
.Select(dbItem=>newitemdto()
{
Id=dbItem.Id,
Label=dbItem.Label,
PriceTag=itemPriceDict[dbItem.Id]//可能的KeyNotFoundException
})
.ToList();
当给定的价格标签不存在时,我有时会得到一个KeyNotFound异常
对于给定的dbItem
现在,当在VisualStudio中调试并引发异常时,您可以看到StackTrace,TargetSite,它显示了触发它的代码行,但是
是否可以找出导致异常的对象(dbItem)并在调试器中显示其数据?例如在手表窗口?
我想:
注:我知道我可以将代码重写为cycle,但我不想这样做。尝试添加另一个语句:
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();
IList itemDTOs=dbItems.Where(dbitem=>dbitem.itemPriceDict[dbitem.Id]!=null)
.Select(dbItem=>newitemdto()
{
Id=dbItem.Id,
Label=dbItem.Label,
PriceTag=itemPriceDict[dbItem.Id]//可能的KeyNotFoundException
})
.ToList();
您可以这样编写选择:
.Select(dbItem =>
{
return new ItemDTO()
{
Id = dbItem.Id,
Label = dbItem.Label,
PriceTag = itemPriceDict[dbItem.Id] // Possible KeyNotFoundException
})
}
.ToList();
这将允许您在select求值中放置断点
更好的方法是,进入“调试”菜单,然后选择“异常”(它位于“我的Visual Studio版本”的Windows子菜单下)
然后设置它,使其在KeyNotFoundException
或您选择的任何异常上中断
当出现异常时,调试器将自动中断,允许您检查相关对象的状态为了进行调试,您可以执行以下操作:
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();
当字典中没有键时,将出现KeyNotFoundException异常。保留一个top变量,并在每次放入Linq查询时分配该键。您可以使用try-and-catch块装饰代码
(KeyNotFoundException ex)
试试看
{
int键;
Dictionary dict=新字典()
{
{1, 2},
{2,3}
};
变量x=(从dict中的y开始)
选择新的
{
value=dict[4]
}).ToList();
}
捕获(KeyNotFoundException ex)
{
//钥匙不在那里
}
捕获(例外情况除外)
{
}
事实证明,检查这样的物体是完全可以的。
下面是正在运行的演示代码:
此外,在Visual Studio 2015中,在运行引发异常的行之前,可以在监视窗口中直接发出Lambda表达式来查询集合
[免责声明:我在OzCode工作]
你试过密码吗。已将Linq调试支持添加到,其中一个功能是它可以预测查询是否会引发异常并显示有问题的项
这样,您就不需要剖析代码或在头脑中调试代码。这是行不通的。您将在Where子句中获得KeyNotFoundException,因为当键不存在时,字典不会返回null。确定尝试这种方式:Where(dbitem=>dbitem.itemPriceDict[dbitem.Id].Any()),但实际上您也会得到KeyNotFound异常。它发生在调用Any()之前的dbitem.itemPriceDict[dbitem.Id]处。您的意思是:Where(dbItem=>itemPriceDict.ContainsKey(dbItem.Id)),但我不想修改任何代码。例如,我希望在调试器视图-观察窗口中看到它。如果您使用Visual Studio,则可以检查是否启用了公共语言运行时异常。可能它会帮助您调试这个问题。@MKasprzyk您搜索的方法在调试时效果很好。但是你必须重写代码。我想在监视窗口或其他地方检查对象,而不必修改现有代码。如果不想更改代码,您的选项非常有限。。。据我所知,如果希望代码保持不变,唯一的选择是在LAMBA表达式(新的ItemDTO部分)内设置断点,然后停止并手动检查字典中的每个ID。编程是一个动态的职业,如果你想得到正确的结果,你必须修改你的代码。当然,我们必须在调试时修改我们的代码。我只是好奇我是否可以在watch window/immediate window中查询对象,这比修改代码、重建和单步执行/运行到断行代码要快。
var missingKeys = dbitems.Where(dbItem => !itemPriceDict.ContainsKey(dbItem.Id)).ToList();
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)
{
}