C# user defined exception - c#

Is it necessary to declare a class in 'public ' visibility mode if the class is defining the user defined exception which extends System.exception class in C#?

It entirely dependes on how you want to use your user defined exception class.
The concept of access modifier is not related at all with the idea of a user defined exception.
A user defined exception is just a user defined class which extends System.Exception, while an access modifier is a construct which specifies the visibility of that class with respect to the client code.
This means that if you just want to use your custom exception class inside the defining assembly you can simply define it as an internal class.
Of course this won't be very useful, because you usually define custom exception class inside class libraries and you want them to be visible in any assembly referencing your class library, so that a consumer can have a chance to handle your custom exception class if it makes sense in his or hers client code.

Try it on DotNetFiddle and see:
public class Foo
{
private class MyException : Exception
{
public MyException(string message) : base(message) { }
}
public static void Throw()
{
throw new MyException("Hello world.");
}
}
public class Program
{
public static void Main()
{
try
{
Foo.Throw();
}
//catch(Foo.MyException myException)
//{
// This doesn't compile
//}
catch(System.Exception exception)
{
Console.WriteLine
(
"Exception is of type '{0}' with a message of '{1}'",
exception.GetType().Name,
exception.Message
);
//Does not compile:
//var typedException = (Foo.MyException)exception;
}
}
}
Output:
Exception is of type 'MyException' with a message of 'Hello world.'
So it turns out you can still catch the exception, inspect its type, and read its base properties, and everything works. But if you want to handle it in a type-safe way and cast it to the specific type, your code won't compile. This also means you can't use a type-specific catch handler.

Related

Can't errors related with instantiating / inheriting class be treated by try~catch statement?

I hope to run the below C# codes to practice usage of abstract / sealed classes :
using System;
abstract class Person
// abstract : can be inherited but can't be instantiated
{
public Person()
{
Console.Write(this + " : ");
}
}
sealed class MichaelJackson : Person
// sealed : can't be inherited but can be instantiated
{
public void Say()
{
Console.WriteLine("Billie Jean is not my lover.");
}
}
class BilleJean : MichaelJackson
// An error will occurs because it tries to inherit a sealed class
{
public void Say()
{
Console.WriteLine("You are the one.");
}
}
class MainClass
{
static void Main(string[] args)
{
try
{
new Person();
// An error will occurs because it tries to be instantiated as an abstract class
}
catch (Exception e)
{
Console.WriteLine("Abstract class can't be instantiated.");
}
new MichaelJackson().Say();
try
{
new BilleJean().Say();
}
catch (Exception e)
{
Console.WriteLine("MichaelJackson : The kid is not my son");
}
}
}
As you know, the abstract class Person can't be instantiated directly and also the sealed class MichaelJackson can't be inherited by the other class BillieJean.
I mean to get the result like the following, but the codes don't run although I've added try~catch statement.
Abstract class can't be instantiated.
MichaelJackson : Billie Jean is not my lover.
MichaelJackson : The kid is not my son.
How can I solve this problem?
You are confusing compiling errors and runtime exceptions.
Trying to inherit a sealed class will produce a compiling error. This means that no executable will be created and that you will not be able to run your code.
A try-catch statement catches exceptions at runtime. E.g., it may catch a "division by 0" exception, but it can not catch a syntax error or a logical error the compiler is complaining about.
The term “runtime” refers to when the code is running. It means that the compiler successfully created an executable file and that you could start it. The compiler can compile successfully when there are warnings (green squiggly lines), code issues or hints (blue squiggly lines), but not when there are errors (red squiggly lines).
The try-catch block only captures run time errors, a.k.a exceptions. What you are getting must be a compile-time error if I am not wrong. Can you verify? Also, your IDE should be displaying an error.

Why is a method of a interface not found by C# dynamic on internal classes?

I tried to use dynamic to access methods of classes that are located in another assembly. These classes are internal and created by builders that return a public interface. For some reason dynamic is not able to invoke the method defined on the interface. I can use "classic" reflection to get the code running but I don't understand why it's not working with dynamic.
I know that dynamic is not working with methods of internal classes but here we have a public interface. So please can someone explain why dynamic throws the RuntimeBinderException in the example below?
namespace SandboxLib // located in SandboxLib.dll
{
public class InternalBuilder
{
public static IInterface Build()
{
return new InternalClass();
}
}
public interface IInterface
{
void IfMethod();
}
internal class InternalClass : IInterface
{
public void IfMethod() { }
}
}
namespace Sandbox // located in Sandbox.dll
{
public class Program
{
static void Main(string[] args)
{
var inst = InternalBuilder.Build();
dynamic dynInst = inst;
inst.IfMethod(); // ok
dynInst.IfMethod(); // Unhandled exception. Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'object' does not contain a definition for 'IfMethod'
}
}
}
This behaviour is described in the C# Standard:
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/expressions#dynamic-binding
Under "Member Lookup" it states:
Member lookup considers not only the name of a member but also the
number of type parameters the member has and whether the member is
accessible.
Since the member IfMethod() that the dynamic resolution has found is internal, the call will fail, as per the specification.

Custom exceptions and base constructor

I've been trying to write my own custom constructor, but getting error about base() constructor. I've also been searching how to solve this error, but found nothing and all the examples round the internet are showing almost the same code as mine.
Whole Exception.cs content:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace RegisService
{
public class Exceptions : Exception
{
}
public class ProccessIsNotStarted : Exceptions
{
ProccessIsNotStarted()
: base()
{
//var message = "Formavimo procesas nestartuotas";
//base(message);
}
ProccessIsNotStarted(string message)
: base(message) {}
ProccessIsNotStarted(string message, Exception e)
: base(message, e) {}
}
}
first overload with base() is working, no errors were thrown. Second and the third
overloads are telling me that :
"RegisService.Exceptions does not contain a constructor that takes
1(2) arguments"
One more way I've been trying to solve the error:
ProccessIsNotStarted(string message)
{
base(message);
}
ProccessIsNotStarted(string message, Exception e)
{
base(message, e);
}
this time, VS is telling me that:
"Use of keyword 'base' is not valid in this context"
So, where is the problem? Looks like the base() constructor has some weird overloads or I'm calling it in inappropriate way?
Your Exceptions class needs to define all constructors you want to provide. The constructors of System.Exception are not virtual or abstract. The keyword base does not call the members of all base classes, but of the one base class you provide in the class declaration. Take a look at this:
public class Exceptions : Exception
{
public Exceptions(string message)
: base(message) {}
}
public class ProccessIsNotStarted : Exceptions
{
public ProccessIsNotStarted()
: base()
{
}
public ProccessIsNotStarted(string message)
: base(message)
{
// This will work, because Exceptions defines a constructor accepting a string.
}
public ProccessIsNotStarted(string message, Exception e)
: base(message, e)
{
// This will not work, because Exceptions does not define a constructor with (string, Exception).
}
}
The parameterless constructor gets defined by default. To hide it you need to declare it private.
Regarding to the MSDN you should keep your exception inheritance hierarchy flat:
If you are designing an application that needs to create its own exceptions, you are advised to derive custom exceptions from the Exception class. It was originally thought that custom exceptions should derive from the ApplicationException class; however in practice this has not been found to add significant value.
You might also take a look at this page.
Remove the Exceptions class entirely and let ProccessIsNotStarted inherit directly from System.Exception.
The constructors of a class are not automatically "copied" to derived classes; they are available using base, but you have to define them manually.
base refers to the immediate base class, not any base class down the chain. Your ProcessIsNotStarted class is a direct subtype of RegisService.Exceptions, not System.Exception. RegisService.Exceptions does not have a constructor with the signature (string, Exception) or (string).
Try adding the two constructors to your RegisService.Exceptions base class.
If you examine the following piece of code:
public class Exceptions : Exception
{
}
You'll notice there are no constructors. Well, that's kind of a lie, because the default public constructor can be used, but there are no custom defined constructors.
If you want to expose the constructors of Exception through Exceptions then you're going to have to define them on Exceptions and call them using base from there, since inheriting exceptions calling base are calling Exceptions, hence Exception isn't their base and therefore the constructors not accessible.
public class Exceptions : Exception
{
Exceptions(string message)
: base(message) { }
Exceptions(string message, Exception e)
: base(message, e) { }
}
Then, you can do new Exceptions("", null) quite fine. And also, your base constructor calling when using inheritance.
Whether or not you get any value from this inheritance chain, I don't know, and you might want to take out the middle man, so to speak, as per another suggestion.

How do we create OnException events on custom baseClass

we have 2 custom class (baseClass and ChildClass) the child class has inherited from the baseClass
when we get a exception on childClass, OnException event on the baseClass should be called
it'll be like MVC Controller OnException Events
We will use for logging.
In the general case it is not possible to do. The MVC OnException works because the framework catches any unhandled exceptions and forwards them to OnException. The framework code for calling a controller action is something like:
try
{
controller.SomeAction();
}
catch(Exception ex)
{
controller.OnException(ex);
}
The entire implementation depends on the caller of the code taking the responsibility to handle the exceptions. With a general calls that can be used by any code you can't make any assumptions on how the class will be called.
If we somehow can make all calls go through the base class we can make something similar:
public class Base
{
public BlahaMethod()
{
try
{
DoBlaha();
}
catch(Exception ex)
{
OnException(ex);
}
}
protected abstract void DoBlaha();
private void OnException(Exception ex)
{
// Handle exception
}
}
public class Derived
{
protected virtual void DoBlaha()
{
throw new NotImplementedException();
}
}
You can catch exception with a try-catch-finally construct. The only general exception handler (known to me) is the unhandled exception handler in the appdomain.

Handle base class exception

I have a following C# scenario-
I have to handle an exception in base class that actually occurs in the derived class.
My base class looks like this:
public interface A
{
void RunA();
}
public class Base
{
public static void RunBase(A a)
{
try
{
a.RunA();
}
catch { }
}
}
The derived class is as follows:
public class B: A
{
public void RunA()
{
try
{
//statement: exception may occur here
}
catch{}
}
}
I want to handle the exception, lets say exception C, that occurs in B(at //statement above).
The exception handling part should be written in base class catch inside RunBase. How can this be done?
public class Base
{
public static void RunBase(A a)
{
try
{
a.RunA();
}
catch(SomeSpecialTypeOfException ex)
{
// Do exception handling here
}
}
}
public class B: A
{
public void RunA()
{
//statement: exception may occur here
...
// Don't use a try-catch block here. The exception
// will automatically "bubble up" to RunBase (or any other
// method that is calling RunA).
}
}
How can this be done?
What do you mean? Just remove the try-catch block from RunA.
Having said that, you need to make sure Class A knows how to handle the exception, this includes streamlining it to UI, logging, ... This is in fact rare for a base class. Handling exception normally happen at the UI level.
public class B: A
{
public void RunA()
{
try
{
// statement: exception may occur here
}
catch(Exception ex)
{
// Do whatever you want to do here if you have to do specific stuff
// when an exception occurs here
...
// Then rethrow it with additional info : it will be processed by the Base class
throw new ApplicationException("My info", ex);
}
}
}
You also might want to throw the exception as it is (use throw alone).
If you dont need to process anything here, dont put try{} catch{}, let the exception bubble up by itself and be processed by the Base class.
Just remove the try catch from class B, if the exception occurs it will propergate up the call chain until it is handled. In this case you can handle the exception in RunBase using your existing try catch block.
Though in your example B isn't derived from your base class Base. If you really want to handle a situation where an exception is thrown in a derived class in its parent you could try something like:
public class A
{
//Public version used by calling code.
public void SomeMethod()
{
try
{
protectedMethod();
}
catch (SomeException exc)
{
//handle the exception.
}
}
//Derived classes can override this version, any exception thrown can be handled in SomeMethod.
protected virtual void protectedMethod()
{
}
}
public class B : A
{
protected override void protectedMethod()
{
//Throw your exception here.
}
}

Categories

Resources