简体   繁体   English

为什么在c#异常类中没有带有1异常参数的构造函数?

[英]Why in c# Exception class does not have a constructor with 1 Exception argument?

System.Exception class has 4 constructors: System.Exception类具有4个构造函数:

public Exception();
public Exception(string message);
protected Exception(SerializationInfo info, StreamingContext context);
public Exception(string message, Exception innerException);

Why it does not have this constructor? 为什么没有此构造函数?

public Exception(Exception innerException);


This is one place where it would have been helpful. 这是一个很有帮助的地方。

I have a static method to get an open connection: 我有一个静态方法来获取打开的连接:

public static DbConnection GetOpenConnection(string dataProvider, string connectionString) 
{
   DbConnection dbConnection = GetDbProviderFactory(dataProvider).CreateConnection();
   dbConnection.ConnectionString = connectionString;
   dbConnection.Open();
   return dbConnection;
}

I want this method to throw a custom exception GetOpenConnectionException if any error occured. 如果发生任何错误,我希望此方法引发自定义异常GetOpenConnectionException

So I created the custom exception GetOpenConnectionException : 因此,我创建了自定义异常GetOpenConnectionException

public class GetOpenConnectionException : Exception
{
   public GetOpenConnectionException(string message) : base(message)
   {
   }
   public GetOpenConnectionException(string message, Exception innerException) : base(message, innerException)
   {
   }
}

Since Exception does not have a constructor public Exception(Exception innerException) , I cannot have this code in GetOpenConnectionException : 由于Exception没有构造函数public Exception(Exception innerException) ,因此我无法在GetOpenConnectionException使用以下代码:

public GetOpenConnectionException(Exception innerException) : base(innerException)
{
}

So I am forced to code the GetOpenConnection() method this way: 因此,我被迫以这种方式编写GetOpenConnection()方法的代码:

public static DbConnection GetOpenConnection(string dataProvider, string connectionString) 
{
   try 
   {
      DbConnection dbConnection = GetDbProviderFactory(dataProvider).CreateConnection();
      dbConnection.ConnectionString = connectionString;
      dbConnection.Open();
      return dbConnection;
   }
   catch (Exception e)
   {
      throw new GetOpenConnectionException("", e);
   }
}

What I wanted is to code the GetOpenConnection() method this way: 我想要的是这样编写GetOpenConnection()方法的代码:

public static DbConnection GetOpenConnection(string dataProvider, string connectionString) 
{
   try 
   {
      DbConnection dbConnection = GetDbProviderFactory(dataProvider).CreateConnection();
      dbConnection.ConnectionString = connectionString;
      dbConnection.Open();
      return dbConnection;
   }
   catch (Exception e)
   {
      throw new GetOpenConnectionException(e);
   }
}

Does this make sense? 这有意义吗?

   public GetOpenConnectionException(Exception innerException) : base("", innerException)
   {
   }

Other answers provide good ways to achieve what you are asking for, but I believe the heart of your question is: "Why didn't this exist in the first place?" 其他答案为满足您的要求提供了很好的方法,但是我相信您的问题的核心是:“为什么这首先不存在?”

Exceptions are normally thrown when a routine's assumptions or prerequisites about the resources it uses and the arguments it asks for are not met. 当不满足例程对它使用的资源以及所请求的参数的假定或先决条件时,通常会引发异常。 The exception thrown should help the caller (or programmer) understand what assumption or prerequisite was not met, so that they can handle it accordingly or fix their code. 引发的异常应有助于调用者(或程序员)了解未满足的假设或先决条件,以便他们可以进行相应处理或修复其代码。 The message is a critical part of that communication. 信息是沟通的关键部分。 I would even hazard a guess that if the Exception class didn't need to be serializable, there wouldn't even be an empty constructor! 我什至会冒险猜测,如果Exception类不需要可序列化,那么甚至没有空的构造函数!

Nesting an exception inside of another implies that the nested exception is the cause of the container exception. 将异常嵌套在另一个内部意味着嵌套异常是容器异常的原因。 (The documentation for that particular constructor of the Exception class points to this a bit.) If you simply pass an inner exception without any message, that effectively translates to "I am going to throw an exception which provides no additional information beyond it's type." (有关Exception类的特定构造函数的文档对此进行了一些说明。)如果仅传递内部异常而没有任何消息,则有效地转换为“我将抛出一个异常,该异常除了其类型外不提供任何其他信息。 ” That's not very helpful, and it would probably have been nicer to simply let the original exception be thrown. 这不是很有帮助,简单地抛出原始异常可能会更好。

Here's one way you could provide a more meaningful message: 这是您可以提供更有意义的消息的一种方法:

public static DbConnection GetOpenConnection(string dataProvider, string connectionString) 
{
   try 
   {
      DbConnection dbConnection = GetDbProviderFactory(dataProvider).CreateConnection();
      dbConnection.ConnectionString = connectionString;
      dbConnection.Open();
      return dbConnection;
   }
   catch (Exception e) // consider changing this to a more specific type of exception, as an error with .Open() is not the only way it could fail
   {
      // provide a meaningful message to the caller about the context of this error
      var message = string.Format("An error occurred while trying to connect to the data provider {0} with the connection string {1}.", dataProvder, connectionString);
      throw new GetOpenConnectionException(message, e);
   }
}

Similar to Piotr Dory's answer, you could do this: 与Piotr Dory的答案类似,您可以执行以下操作:

public GetOpenConnectionException(Exception innerException) :
    base(innerException.message, innerException)
{
}

This way you're actually passing something meaningful into the base constructor. 这样,您实际上将有意义的东西传递给了基本构造函数。

As to why there isn't a constructor that only takes an Exception argument... it doesn't seem there is actually a good reason. 至于为什么没有只接受Exception参数的构造函数……似乎实际上没有充分的理由。 They easily could have. 他们很容易拥有。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM