【问题标题】:C# Selected Overload Method On RuntimeC# 在运行时选择重载方法
【发布时间】:2017-08-30 19:47:23
【问题描述】:
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 作为参数的特定重载方法并被称为带有异常的方法?

【问题讨论】:

  • 你的问题不清楚。请添加更多描述
  • Idk 这里有什么不清楚的地方:o

标签: c# inheritance exception-handling overloading


【解决方案1】:

在下面的 try/catch 块中:

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

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

如果你想捕捉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,如下:

异常具有以下属性:

  • 异常是所有最终从 System.Exception 派生的类型。
  • 一旦 try 块中发生异常,控制流将跳转到第一个关联的异常处理程序 调用堆栈中的任何位置。在 C# 中,catch 关键字用于定义 异常处理程序。

除了上述内容之外,您会发现this 的内容很有帮助,其中指出

可以将具有不同异常过滤器的多个 catch 块链接在一起。 catch 块在您的代码中从上到下进行评估,但是 每个抛出的异常只执行一个 catch 块。 第一个指定确切类型或基类的 catch 块 抛出的异常被执行。如果没有 catch 块指定一个 匹配异常过滤器,一个没有过滤器的catch块 被选中,如果语句中存在一个。 重要的是 定位最具体(即最 派生的)异常类型优先

【讨论】:

  • 这与异常无关。问题是重载的方法是在 compile 时绑定的。
  • @N73k 我不同意你的说法。原因是要调用的重载方法取决于捕获异常的类型。这实际上也是我在回答中试图解释的,可能不太好。我已经写了抛出了一个异常,并且异常的类型是Exception,而不是BaseException。正如您所说,这意味着将调用重载方法MethodA(Exception e)。因此,调用者处理抛出异常的方式会在编译时影响,这将是绑定的方法。
  • 问题是这个问题并不特定于这个 try-catch-exception 事情。问题比这更普遍。它不仅发生在 try-catch-exception 中,而且无处不在。
  • 你怎么能解释这个没有考虑到异常的处理。我认为这是不可能的,因为即使您开始谈论在编译时绑定重载方法(这绝对是正确的),如果不从异常类型开始,您也无法解释在这种情况下它是如何工作的 以及如何处理它们。老实说,如果您能完全不讨论例外情况,对这个非常具体的案例进行解释,我将不胜感激。
【解决方案2】:

重载的方法在编译时绑定。 在编译时,e 的类型为 Exception。 就是这个原因。

方法是否是静态的并不重要。这是两者的编译时间。

但是在你捕捉到异常之后你可以做

dynamic dynEx = e;
MethodA(dynEx);

你会得到正确的调用方法。

【讨论】:

    【解决方案3】:

    函数MethodA 被声明为静态。因此,任何与函数的绑定都是在编译时进行的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-22
      • 2023-03-09
      • 1970-01-01
      相关资源
      最近更新 更多