C# 奇怪的尝试/捕获行为

C# 奇怪的尝试/捕获行为,c#,oracle,exception,C#,Oracle,Exception,我有一个简单的try/catch块 try { // Open the connection _connection.Open(); // [1] } catch( OracleException ex ) // [2] { // Handle the exception int x = ex.ErrorCode; } 捕获从未执行,运行时报告[1]中的“OracleException未处理”,这让我头晕目眩。显然,我有一个关联异常类型的catch语句。

我有一个简单的try/catch块

try
{
     // Open the connection
     _connection.Open(); // [1]
}
catch( OracleException ex ) // [2]
{
     // Handle the exception
     int x = ex.ErrorCode;
}
捕获从未执行,运行时报告[1]中的“OracleException未处理”,这让我头晕目眩。显然,我有一个关联异常类型的catch语句。我甚至在[2]尝试了完全限定的类型Oracle.DataAccess.Client.OracleException,但该异常仍未处理


我唯一能真正让catch生效的方法是捕获[2]中的System.Exception。是什么导致了这种奇怪的行为

您可能希望捕获更一般的
DbException

try
{
     // Open the connection
     _connection.Open(); // [1]
}
catch( DbException ex ) // [2]
{
     // Handle the exception
     int x = ex.ErrorCode;
}

您是否使用
Assembly.LoadFrom
或类似工具动态加载程序集?如果是这样的话,您可能会遇到这样的情况:您已经将多个类型加载到不同的加载上下文中

加载到不同上下文中的程序集呈现具有不同标识的相同类型,因此它们不匹配类型相等性检查等

  • 加载上下文包含程序集 通过探测发现:在GAC中,在 宿主程序集存储(如果运行时为 托管,或在ApplicationBase和 应用程序的PrivateBinPath 域名。负载的大多数重载 方法将程序集加载到此 上下文

  • 从上下文加载包含 用户为其配置的程序集 提供了未包含在 通过探测搜索的目录。 LoadFrom、CreateInstanceFrom和 ExecuteAssembly是 按路径加载的方法


当然,这只是一个猜测,所以我可能错了。

可能它抛出的是Oracle.DataAccess.Client.OracleException,而不是Oracle.DataAccess.Client.OracleException。我知道这听起来很奇怪,但有可能将两种名称完全相同的类型加载到给定的AppDomain中

试试这个

try 
{ 
     // Open the connection 
     _connection.Open(); // [1] 
} 
catch( Exception ex ) // [2] 
{ 
     if (ex.GetType() == typeof(OracleException)) Debug.WriteLine("is match");
     else Debug.WriteLine ("is not match");

     // Handle the exception 
     int x = ex.ErrorCode; 
} 
另一种可能性是异常被包装。您可能会收到包含OracleException的InvalidOperationException


最后,错误可能就在try块之后。您可能误读了堆栈跟踪,或者堆栈跟踪中的行号错误。这两种情况总是发生在我身上。

当你捕获异常时当你编写异常时会打印什么?例如GetType().ToString()?听起来OracleException被包装在不同类型的异常中。完整堆栈跟踪说明了什么?当捕获为异常时,它返回“Oracle.DataAccess.Client.OracleException”因此,看起来您要么需要键入异常的完整名称,要么需要捕获一个更通用的版本,例如
DbException
,它是基本的ADO.NET异常。听起来您和我有相同的理论。这是一个很好的建议,我将检查GAC。我知道我的工作站安装了两个版本的Oracle ODP客户端。我打赌这是个问题。愚蠢的C#和它缺乏拼写检查。我不知道为什么它不像VB那样为我处理这些事情。(这本身就很奇怪,因为VB的编译器不在乎你如何大写关键字。)我认为你和克里斯走对了方向。我之前意识到,InvalidCastException导致了一个错误,即无法将Oracle.DataAccess.Client.OracleException强制转换为Oracle.DataAccess.Client.OracleException。对我来说,这似乎是一个版本问题,对吗?很好的建议,希望我能选择两个正确的答案。你和克里斯的想法是对的。加载了两种相同名称的类型!问题已解决。