[英]liskov substitution principle and exception handling
它说Derived类不应该抛出Base类不知道的任何异常,我试图找到它的工作方式,在基类中我抛出System.Exception并且在Derived中我抛出了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");
}
}
}
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
。 现在,任何只知道基类的人都只有ArgumentNullException
catch块,因为这是他们所期望的。 因此,当子类抛出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+substitution+principle
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.