Reputation: 501
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");
}
}
}
Upvotes: 2
Views: 2024
Reputation: 7724
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.
Upvotes: 1
Reputation: 101150
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
}
}
}
Upvotes: 8