принцип подстановки Лискова и обработка исключений
Он говорит, что производный класс не должен выбрасывать какое-либо исключение, которое не известно базовому классу, я пытаюсь найти, как его работа, в базовом классе я выбрасываю систему.Исключение и в производном я бросаю ArgNullException (). Может кто-нибудь объяснить, это нормально
class b
{
virtual public void foo()
{
try
{
if (true)
throw new System.Exception();
}
catch (Exception ex)
{
Console.WriteLine("in base");
}
}
}
class a : b
{
override public void foo()
{
try
{
if (true)
throw new ArgumentNullException();
}
catch (Exception ex)
{
Console.WriteLine("in dervied");
}
}
}
3 ответа:
class MyClass { public virtual void Foo() { if (true) throw new System.Exception(); } } } class MyDerivedClass : MyClass { public override void Foo() { if (true) throw new ArgumentNullException(); } } } public class Program { public static void Main() { try { // a factory creating the correct // MyClass derived instance var myClass = someFactory.Create(); myClass.Foo(); } catch (Exception) { // will work. } } }В этом случае вы создаете наименее конкретное исключение, возможное в базовом классе (почему это отстой-это еще один разговор). Как и в этом случае, любой, кто использует подклассы, сможет поймать это, независимо от того, какое конкретное исключение вы создадите.
Скажем, что это был другой путь вокруг. Базовый класс бросает
ArgumentNullExceptionи подклассException. Теперь любой, кто только знает о базовом классе, будет иметь только блоки catch дляArgumentNullException, поскольку это то, что они ожидают. Их поэтому приложение не будет работать, когда подкласс бросаетException.class MyClass { public virtual void Foo() { if (true) throw new ArgumentNullException(); } } } class MyDerivedClass : MyClass { public override void Foo() { if (true) throw new Exception(); } } } public class Program { public static void Main() { try { // a factory creating the correct // MyClass derived instance var myClass = someFactory.Create(); myClass.Foo(); } catch (ArgumentNullException) { // won't work since the subclass // violates LSP } } }
В опубликованном коде нет проблем с подтипами, потому что в обоих случаях вы ловите исключение в той же области, в которой оно было вызвано. Но предположим, что производные
fooне было предложения catch , и базовый класс имел следующий код:try { this.foo(); } catch (ArgumentOutOfRangeException e) { ... }Базовый класс делает предположение, что
fooтолько бросает ArgumentOutOfRange, который производный класс нарушил бы, бросив ArgumentNull.
Более полное понимание принципа замещения Лискова можно найти здесь
https://stackoverflow.com/search?q=liskov + замещение + Принцип