简体   繁体   English

liskov替换原则和异常处理

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM