Question

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(). 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");
                }
            }           

        }
Was it helpful?

Solution

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. Now, anyone only knowing about the base class would only have catch blocks for ArgumentNullException as that is what they expect. Their application will therefore fail when the sub class throws 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
        }
    }
}

OTHER TIPS

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:

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top