So I'll be honest, this is for a homework assignment. I know how to use try and catch, but I'm not quite sure what this question is asking, I'm not asking for the answer, just a clarification.
The Question:
Use inheritance to create an exception base class and various exception-derived classes. Write a program to demonstrate that the catch specifying the base class catches derived-class exceptions.
My basic train of thought is that I just make a new class called say.. "Exceptionz" and inherit from System.Exception, make several classes called say, "Derived 1", "Derived 2", then have each of those inherit from "Exceptionz". After that, I am not sure what the question is asking me to do.
Thanks for the help in advance!
It's asking you to create the exceptions as you suggested (Exceptionz as your base class, deriving from Exception, then two more classes, Derived1 and Derived2 that use Exceptionz as their base), then do something like this:
try
{
throw new Derived1();
}
catch (Exceptionz)
{
Console.WriteLine("Caught Derived 1");
}
try
{
throw new Derived2();
}
catch (Exceptionz)
{
Console.WriteLine("Caught Derived 2");
}
So you're showing that catching your base class (Exceptionz) also catches any of its derived exceptions (Derived1 and Derived2). Similar to how you may have an "I/O Exception" exception, then more specific ones deriving from it for permission denied, file not found etc.
Related
https://learn.microsoft.com/en-us/dotnet/api/system.applicationexception?view=net-5.0 says that "ApplicationException Class" Serves as the base class for application-defined exceptions. But in an example at https://learn.microsoft.com/en-us/dotnet/standard/exceptions/how-to-create-user-defined-exceptions custom exception class derives from "Exception" base class.
Well, MSDN states clearly
Important
You should derive custom exceptions from the Exception class rather
than the ApplicationException class. You should not throw an
ApplicationException exception in your code, and you should not catch
an ApplicationException exception unless you intend to re-throw the
original exception.
So for custom exception we should use Exception as a base class
Fundamentally, it doesn't matter. If your exception type would be a better logical fit when derived from one of the system-provided exceptions, as a user I'd prefer that kind of implementation. Think about what happens when user of your code catches the exceptions, and plan accordingly.
Microsoft's Best Practice says:
Introduce a new exception class only when a predefined one doesn't apply.
And:
When a custom exception is necessary, name it appropriately and derive it from the Exception class.
Deriving from the Exception class makes sense because that makes it possible for us to handle specific exceptions and (for example) log and throw the rest:
try
{
//something that might throw exceptions
}
catch(InvalidOperationException)
{
//Do something
}
catch(Exception ex)
{
//Log and throw other exception
throw;
}
I cant think of a reason why one would want to create an instances of the Exception base class. So why is Exception not marked as an abstract class?
I thought catching an abstract Exception might cause some special behaviour, but that does not seem to be the case:
public abstract class AbstractException : Exception
{
}
public class MyException : AbstractException
{
}
//...
try
{
throw new MyException();
}
catch (AbstractException)
{
//Works fine
}
Abstract classes are only required when there are abstract members. Exception doesn't have those so it doesn't require to be abstract.
But Microsoft could make it abstract to comply to their own best practices. Well, best practices are not set in stone, so a developer should have the choice to deviate from them. The non-abstract Exception provides that possibility.
There are lot of cases when you don't need any special or additional information to "describe" an exceptional situation in a computation flow. The Exception type is very suitable for such situations so that you don't have to define a new types for the generic exceptional situations. Being an abstract type the Exception wouldn't allow you to instantiate it and you'll have to invent some generic exception types from project to project in order to have an exception type "understandable" by all high-level consumers (that is provide a way to all consumers to catch and handle all exceptions regardless of an exception type specialization).
One thing i need to be clear. When using inheritance i can override a method without using any virtual or override keyword. My program also running and giving correct output. Then why do we have override concept even though we have inheritance. How it differs?
here is my code
class InheritanceDemo
{
public void Mymeth()
{
Console.WriteLine("this is base");
}
}
class A1 : InheritanceDemo
{
public void Mymeth()
{
Console.WriteLine("this is derived");
}
}
Main method:
static void Main(string[] args)
{
InheritanceDemo a = new A1();
A1 b = new A1();
a.Mymeth();
b.Mymeth();
}
output:
this is base
this is derived
Function overriding is needed when the derived class function has to do more or different job than the base class function.
These concepts becomes important in large scale application where problem is big so, u first create an abstract class (which just gives the ideas about how things might be rather than the direct implementation). These Abstract class can contain virtual methods (member functions) that any member of group working on has to implement (as virtual methods have to be defined in the derived class).
I think u got my point... :)
Why do you think the output is "correct"? With inheritance you want to call the correct inherited function and not a method in your base class. And that's what you define with virtual/override.
When you compiled this you should have got a warning CS0108.
Do not ignore warnings. Indeed, if you can set your compilation to error rather than warn. Warnings are generally a sign that you've done something bad or at best unclear. They aren't errors because you might have a good reason for doing something that looks bad or unclear at first look, but in the case of hiding instead of overriding we have new.
What you have here is not an override, though as you seem to expect, generally what you would want here is an override. That's part of why this code produces a compiler warning.
My program also running and giving correct output
Maybe it's correct, but it's not correct if you expected an override. If it was overriding you should have "this is derived" output by both.
If it is correct, it's a bad design, because people generally expect overrides. You can stop the warning by changing A1.Mymeth to be defined as public new void Mymeth() which is a way to flag "I really meant to do this thing that looks wrong", but if you have to explain yourself, that's a bad sign. Hiding methods is generally only to be done when someone changing a base class under you forces your hand, you need to match names due to some sort of interoperability and a small number of other very rare cases.
Logically the methods in question should be abstract but they are on a parent form that gets inherited from and Visual Studio will have fits if they are declared abstract.
Ok, I made the bodies throw a NotImplementedException. Resharper flags that and I'm not one to tolerate a warning in the code like that.
Is there an elegant answer to this or do I have to put up with some ugliness? Currently I am doing:
protected virtual void SaveCurrentItem()
{
Trace.Assert(false, "Only the children of FormCore.SaveCurrentItem should be called");
}
protected virtual void SetItem()
{
Trace.Assert(false, "Only the children of FormCore.SetItem should be called");
}
The class itself should never be instantiated, only its children. However, Visual Studio insists on creating one when you look at the designer of one of its children.
You might consider creating a nested, protected interface. For example:
protected interface IManageItems
{
void SaveCurrentItem();
void SetItem();
}
Each class that inherits from FormCore could individually implement the interface. Then you wouldn't have the risk of calling the base class implementation because there wouldn't be any.
To call the methods from your base class:
(this as IManageItems)?.SaveCurrentItem();
This would have the effect of making the methods act as if they were virtual without having an initial declaration in the parent class. If you wanted to force a behavior that was closer to abstract, you could check to see if the interface was being implemented in the constructor of the base class and then throw an exception if it wasn't. Things are obviously getting a little wonky here, because this is essentially a workaround for something the IDE is preventing you from doing, and as such there's no real clean, standard solution for something like this. I'm sure most people would cringe at the sight of a nested protected interface, but if you don't want an implementation in your base class and you can't mark your base class abstract, you don't have a lot of options.
Another thing to consider is favoring composition over inheritance to provide the functionality that you need.
On the other hand instead of using an interface, it may be appropriate to simply throw a NotSupportedException in a circumstance where the class cannot perform the action. NotImplementedException is designed to be used for in-development projects only, which is why ReSharper is flagging the method.
NotSupportedException: The exception that is thrown when an invoked method is not supported, or when there is an attempt to read, seek, or write to a stream that does not support the invoked functionality.
One use case is:
You've inherited from an abstract class that requires that you override a number of methods. However, you're only prepared to provide an implementation for a subset of these. For the methods that you decide not to implement, you can choose to throw a NotSupportedException.
See NotSupportedException documentation on MSDN for more information and usage guidelines.
Resharper raises the warning to alert users that code has not been completed. If your actual desired behaviour is to not support those methods, you should throw a NotSupportedException instead of NotImplementedException, to make your intentions clearer.
In a follow-up to a previous question regarding exceptions, what are best practices for creating a custom exception in .NET?
More specifically should you inherit from System.Exception, System.ApplicationException or some other base exception?
In the C# IDE, type 'exception' and hit TAB. This will expand to get you started in writing a new exception type. There are comments withs links to some discussion of exception practices.
Personally, I'm a big fan of creating lots of small classes, at that extends to exception types. For example, in writing the Foo class, I can choose between:
throw new Exception("Bar happened in Foo");
throw new FooException("Bar happened");
throw new FooBarException();
where
class FooException : Exception
{
public FooException(string message) ...
}
and
class FooBarException : FooException
{
public FooBarException()
: base ("Bar happened")
{
}
}
I prefer the 3rd option, because I see it as being an OO solution.
Inherit from System.Exception. System.ApplicationException is useless and the design guidelines say "Do not throw or derive from System.ApplicationException."
See http://blogs.msdn.com/kcwalina/archive/2006/06/23/644822.aspx
There is a code snippet for it. Use that. Plus, check your code analysis afterwards; the snippet leaves out one of the constructors you should implement.
I think the single most important thing to remember when dealing with exceptions at any level (making custom, throwing, catching) is that exceptions are only for exceptional conditions.
The base exception from where all other exceptions inherit from is System.Exception, and that is what you should inherit, unless of course you have a use for things like, say, default messages of a more specific exception.