C# 在运行时选择重载方法

标签 c# inheritance exception overloading

namespace Rextester
{
    public class BaseException : Exception
    {
        public BaseException() { }
    }

    public class Program
    {
        public static void MethodA(BaseException e)
        {
            Console.WriteLine("BaseException");
        }

        public static void MethodA(Exception e)
        {
            Console.WriteLine("Exception");
        }

        public static void Main(string[] args)
        {
            try
            {
                throw new BaseException();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.GetType());
                MethodA(e);
            }
        }
    }
}

大家好,根据上面执行代码的结果,我有一个问题:

e.GetType() == Rextester.BaseException

MethodA 写入控制台:异常

因此,即使异常的类型是派生类,为什么在运行时不调用具有 BaseException 作为参数的特定重载方法,而是调用具有异常的方法?

最佳答案

在以下 try/catch block 中:

try
{
    throw new BaseException();
}
catch (Exception e)
{
    Console.WriteLine(e.GetType());
    MethodA(e);
}

异常被抛出,异常的类型是 Exception,而不是 BaseException。基本上,您抛出一个 BaseException,但是 BaseException 继承了 Exception。所以你进入了 catch block 。

如果您想捕获 BaseException,您应该首先捕获它,因为它更具体。

try
{
    throw new BaseException();
}
catch (BaseException e)
{
    Console.WriteLine(e.GetType());
    MethodA(e);
}
catch (Exception e)
{
    Console.WriteLine(e.GetType());
    MethodA(e);
}

顺便说一句,DerivedException这个名字比BaseException这个名字更清楚。 .NET 中的所有异常类型以及自定义异常类型(我们根据需要定义的异常类型)都继承自 Exception 类。所以它们都是 Exception 类的派生类。

以上也可以查到here如下:

Exceptions have the following properties:

  • Exceptions are types that all ultimately derive from System.Exception.
  • Once an exception occurs in the try block, the flow of control jumps to the first associated exception handler that is present anywhere in the call stack. In C#, the catch keyword is used to define an exception handler.

除上述内容外,this 的内容也会对您有所帮助, 它指出

Multiple catch blocks with different exception filters can be chained together. The catch blocks are evaluated from top to bottom in your code, but only one catch block is executed for each exception that is thrown. The first catch block that specifies the exact type or a base class of the thrown exception is executed. If no catch block specifies a matching exception filter, a catch block that does not have a filter is selected, if one is present in the statement. It is important to position catch blocks with the most specific (that is, the most derived) exception types first.

关于C# 在运行时选择重载方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45968602/

相关文章:

c++ - 派生类指针如何调用基类函数

c# - ExecuteNonQuery() 异常未被 try-catch 捕获

java - 自定义异常中的 super 调用

c# - 使用 MailKit (C#) 转发电子邮件

Java 继承 - 找不到在对象上调用的方法?

c# - 如何强制结束 Parallel.Invoke 循环?

C++ 类继承段错误

c# - 锁定构造函数导致空引用?

c# - "Analyzer with Code Fix"项目模板已损坏

c# - 在 listview winform c# 中列出 S3 Bucket 键