[英]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.