Можем ли мы перехватить исключение из метода дочернего класса в базовом классе в C #?

#c#

#c#

Вопрос:

В интервью интервьюер задал мне этот вопрос. Можем ли мы перехватить исключение, вызванное методом дочернего класса в базовом классе? Я сказал «нет», но он сказал «да», это возможно. Итак, я хочу знать, возможно ли это вообще, и если да, пожалуйста, приведите мне какой-нибудь практический пример. Вам не нужно вызывать метод базового класса. Спасибо.

Комментарии:

1. В каком контексте? Если вы имеете в виду виртуальный метод, который переопределяется напрямую, то базовый класс не может перехватить исключение, выданное в дочерней реализации.

Ответ №1:

Вот простой пример, в котором базовый класс перехватывает исключение из производного класса.

 abstract class Base
{
    // A "safe" version of the GetValue method.
    // It will never throw an exception, because of the try-catch.
    public bool TryGetValue(string key, out object value)
    {
        try
        {
            value = GetValue(key);
            return true;
        }
        catch (Exception e)
        {
            value = null;
            return false;
        }
    }

    // A potentially "unsafe" method that gets a value by key.
    // Derived classes can implement it such that it throws an
    // exception if the given key has no associated value.
    public abstract object GetValue(string key);
}

class Derived : Base
{
    // The derived class could do something more interesting then this,
    // but the point here is that it might throw an exception for a given
    // key. In this case, we'll just always throw an exception.
    public override object GetValue(string key)
    {
        throw new Exception();
    }
}
 

Комментарии:

1. Предполагая, что G() = GetValue() ?

Ответ №2:

Вот и все:

 public class BaseClass
{
    public void SomeMethod()
    {
        try
        {
            SomeOtherMethod();
        }
        catch(Exception ex)
        {
            Console.WriteLine("Caught Exception: "   ex.Message);
        }
    }

    public virtual void SomeOtherMethod()
    {
        Console.WriteLine("I can be overridden");
    }
}

public class ChildClass : BaseClass
{
    public override void SomeOtherMethod()
    {
        throw new Exception("Oh no!");
    }
}
 

SomeMethod , определенный в базовом классе, вызывает другой метод SomeOtherMethod того же объекта и улавливает любые исключения. Если вы переопределяете SomeOtherMethod в каком-то дочернем классе и он выдает исключение, то оно перехватывается в SomeMethod defined в базовом классе. Язык, используемый в вашем вопросе, немного неоднозначен (технически во время выполнения он по-прежнему ChildClass выполняет обработку исключений), но я предполагаю, что это то, к чему клонил ваш интервьюер.

Другая возможность (опять же, в зависимости от интерпретации) заключается в том, что экземпляр базового класса вызывает метод другого объекта, который наследует указанный базовый класс, который генерирует исключение (а затем перехватывает исключение):

 public class BaseClass
{
    public void SomeMethod()
    {
        var thing = new ChildClass();
        try
        {
            thing.ThrowMyException();
        }
        catch(Exception ex)
        {
            Console.WriteLine("Exception caught: "   ex.Message);
        }
    }
}

public class ChildClass : BaseClass
{
    public void ThrowMyException()
    {
        throw new Exception("Oh no!");
    }
}
 

Здесь при BaseClass.SomeMethod вызове экземпляр базового класса перехватывает исключение, выданное в другом экземпляре дочернего класса.