为什么无法访问异常的 .Error 属性?

huangapple go评论74阅读模式
英文:

Why can't I access an Exception's .Error property?

问题

我有一个程序会抛出一个名为 ODataError 的图形异常。我的 catch 只是将它捕获为一个通用异常:

catch (Exception ex) {
    Log.Write(ex);
}

当我在 catch 上设置断点时,可以悬停在 ex 对象上并深入查看其属性:

为什么无法访问异常的 .Error 属性?

但如果我在即时窗口中输入以下内容,会得到这个结果:

ex.Error

为什么无法访问异常的 .Error 属性?

所以,当然,任何尝试访问 ex.Error.Message 也会得到 "undefined"。

我如何才能引用到内部的 ex.Error.Message

英文:

I have a program that throws a Graph ODataError exception. My catch simply catches the exception as a generic exception:

catch (Exception ex) {
	Log.Write(ex);
}

When I put a breakpoint on the catch, I can hover over the ex object and drill down into its properties:

为什么无法访问异常的 .Error 属性?

But if I type the following in the immediate window, I get this:

ex.Error

为什么无法访问异常的 .Error 属性?

So, of course, any attempt to ex.Error.Message is also "undefined".

How can I get a reference to that inner ex.Error.Message?

答案1

得分: 6

IntelliSense弹出窗口允许您使用检查的对象实际底层类型来进行分析。然后,它将使用反射来显示和公开该对象提供的一切,无论检查的变量的类型如何。

Immediate窗口允许您执行代码片段,就像您在自己的代码中编写它们一样。但是,此代码必须遵守当前作用域中变量声明的类型。

您有几个选项:

如果您想在实际代码中使用属性,最好实际捕获您想要处理的特定异常类型。如果适用,您还可以使用共同的超类。例如,您可以使用catch (OperationCanceledException ex)来捕获任何OperationCanceledException,以及派生的TaskCanceledException。在这种情况下,ex将使您能够访问来自OperationCanceledException及其超类的所有内容,但不能访问特定于派生类的内容。这实际上是您在那里所做的,但通过选择最广泛的超类System.Exceptionex实际上无法提供太多特定的见解,除了Exception类在类型层次结构顶级已经引入的所有内容。

如果您只想在Immediate窗口中临时检查它,可以在您的代码行中添加一个简单的转换:((ODataError) ex).Error.Message

或者,根据您的使用情况(这也是从本地上下文继承的),您可能需要完全引用它,如下所示:((Microsoft.Graph.Models.ODataErrors.ODataError) ex).Error.Message

英文:

The IntelliSense popup allows you to analyze the object using the actual underlying type that the inspected object has. It will then use reflection to display and expose everything that object has to offer, regardless of the type of the inspected variable.

The Immediate Window allows you to execute bits of code as if you had written them in your own code. This code however must respect the declared type of the variables in the current scope.

You have several options here:

If you want to use the properties in your actual code, it's best to actually catch the specific exception type you want to handle. If applicable, you may also use a common superclass. For example, you can use catch (OperationCanceledException ex) to catch any OperationCanceledException, as well as the derived TaskCanceledException. In that case, ex will give you access to everything from OperationCanceledException and its superclasses, but not from things specific to derived classes. This is actually what you did there, but by chosing the most broad superclass System.Exception, there isn't really much specific insight ex can offer, apart from all things that the Exception class already introduced at the top level of the type hierarchy.

If you only want to inspect it temporarily within the immediate window, you can add a simple cast to your code line: ((ODataError) ex).Error.Message

Or, depending on your usings (which are also inherited from the local context), you may need to fully reference it, like so: ((Microsoft.Graph.Models.ODataErrors.ODataError) ex).Error.Message

答案2

得分: 0

如果你只想从对较不具体类型的引用中访问属性,你也可以使用 ```is``` 操作符:

var msg = ex is Microsoft.Graph.Models.ODataErrors.ODataError odataErr?
odataErr.Error?.Message :
ex.Message;

如果可能的话,这将给你 ```ODataError.Error.Message```,否则将给你 ```Exception.Message```。
英文:

If you only want to access a property from a reference to a less-specific type, you could also use the is operator:

var msg = ex is Microsoft.Graph.Models.ODataErrors.ODataError odataErr?
    odataErr.Error?.Message : 
    ex.Message;

This should give you the ODataError.Error.Message if possible or the Execption.Message otherwise.

huangapple
  • 本文由 发表于 2023年7月14日 00:04:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/76681384.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定