考虑以下分析器:
public void AnalyzeNode(SyntaxNode node, SemanticModel semanticModel, Action<Diagnostic> addDiagnostic, CancellationToken cancellationToken)
{
var throwStatement = node as ThrowStatementSyntax;
var isObjectCreationExpression = throwStatement.Expression is ObjectCreationExpressionSyntax;
var obj = throwStatement.Expression as ObjectCreationExpressionSyntax;
var isCorrectTypeOfExpression = (obj.Type as IdentifierNameSyntax).Identifier.Text == typeof(ArgumentException).Name;
}
以SyntaxKind.ThrowStatement
作为兴趣点。
obj
如果在null
表单中未正确声明抛出的异常,则应为new Exception()
,而应显示为throw e
其中e
为先前宣布的例外。
这会在NullReferenceException
之后立即调出obj.Type
。
有问题的例子:
static void Method1()
{
throw new ArgumentException();
}
static void Method2(ArgumentException e)
{
throw e;
}
第一个throw
会很好地通过分析器,但第二个obj
会导致null
为ObjectCreationExpressionSyntax
,因为它不是1
类型。
在沙盒Visual Studio环境中,这将显示为信息消息:
用户诊断分析器&#39; FormattingFixes.EmptyArgumentException.ArgumentExceptionAnalyzer&#39;在消息&#39;对象引用未设置为对象实例的情况下抛出异常。&#39;。
在这个简短的样本中,很容易分辨问题所在,但在一个不那么人为的例子中,它将更难被发现。行和列都是{{1}},没有帮助。
传统&#34;编程时,您的环境会自动显示抛出运行时异常的位置以及该时间点的值。我可以在我的代码中的某个地方放置一个随机断点,每次点击时查看所有值,并尝试从那里推断出它,但是一旦节点数远远高于这些值,这就不能很好地扩展。 2。
我们如何轻松找到代码中的哪一行导致运行时异常?
答案 0 :(得分:5)
所以你应该还是休息一下,但是如果你没有要检查的东西:
转到“调试”菜单下,然后选择“例外”。您将看到“Thrown”或“User-unhandled”列。使用Find查找NullReferenceException,并选中“thrown”复选框。一旦抛出NullReferenceException,这将导致VS中断。如果你想要非常积极,你可以告诉它打破所有例外。
如果仍无效,请转到工具&gt;选项,调试,常规和清除“只是我的代码”。这里需要注意的是,这会破坏所有异常,包括VS中甚至不是你的错误的部分。 (可悲的是,我们在很多不同的地方都抛出了很多例外。)
如果您愿意,请随意file a bug,以便我们可以将消息包括堆栈跟踪和行/列,以便更容易调试。
因为我在这里:你的代码确实
var isCorrectTypeOfExpression = (obj.Type as IdentifierNameSyntax).Identifier.Text == typeof(ArgumentException).Name;
注意语法检查 - 如果我写throw new System.ArgumentException()
会怎样?正确的方法是获取语义模型并绑定ObjectCreationExpression以确定实际类型是什么。 (如果你在意的话,这也意味着你在别名的情况下工作。)
答案 1 :(得分:-1)
使用以下步骤获取引发异常的行号。
以下是代码段。
try
{
//TODO
throw new Exception();
}
catch (Exception ex)
{
var stacktrace = new StackTrace(ex, true);
var frame = st.GetFrame(0);
var filelinenumber = frame.GetFileLineNumber();
}