[英]liskov substitution principle and exception handling
It says that Derived class should not throw any exception which is not known to the Base class, i am trying to find how its work, in the base class i am throwing System.Exception and in Derived i am throwing ArgNullException(). 它说Derived类不应该抛出Base类不知道的任何异常,我试图找到它的工作方式,在基类中我抛出System.Exception并且在Derived中我抛出了ArgNullException()。 Can someone explain is this is fine
有人可以解释这是好的
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.
}
}
}
In this case you are throwing the least specific exception possible in the base class (why that sucks is another discussion). 在这种情况下,您可以在基类中抛出最少的特定异常(为什么这很糟糕是另一个讨论)。 As in such, anyone using the sub classes will be able to catch that, no matter how specific exception you throw.
就像这样,任何使用子类的人都能够捕获它,无论你抛出多么具体的异常。
Let's say that it had been the other way around. 让我们说它反过来了。 The base class throws
ArgumentNullException
and the sub class Exception
. 基类抛出
ArgumentNullException
和子类Exception
。 Now, anyone only knowing about the base class would only have catch blocks for ArgumentNullException
as that is what they expect. 现在,任何只知道基类的人都只有
ArgumentNullException
catch块,因为这是他们所期望的。 Their application will therefore fail when the sub class throws Exception
. 因此,当子类抛出
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
}
}
}
In the code you posted, there is no issue in terms of subtypes, because in both cases you are catching the exception in the same scope that it's thrown. 在您发布的代码中,子类型没有问题,因为在这两种情况下,您都会在抛出异常的范围内捕获异常。 But suppose the derived
foo
did not have a catch clause , and the base class had the following code: 但是假设派生的
foo
没有catch子句 ,并且基类具有以下代码:
try {
this.foo();
} catch (ArgumentOutOfRangeException e) {
...
}
The base class is making the assumption that foo
only throws ArgumentOutOfRange, which the derived class would be violating by throwing ArgumentNull. 基类假设
foo
只抛出ArgumentOutOfRange,派生类会抛出ArgumentNull而违反。
A better understanding of the Liskov's sustitution principle can be found here 可以在此处找到对利斯科夫的替代原则的更好理解
https://stackoverflow.com/search?q=liskov+substitution+principle https://stackoverflow.com/search?q=liskov+substitution+principle
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.