Custom exceptions and base constructor - c#

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.

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.

How to create a C# abstract proxy class for an interface where all interface methods are required on the proxy?

I'm trying to create an abstract proxy for several interfaces. Obviously both a concrete proxy implementation and the concrete proxied class it 'fronts' must implement the same interface. The proxy accepts the proxied class (to proxy to). Ideally I wouldn't constrain the interfaces at all but I don't believe C# allows constraining a generic type to being an interface. As such, my sample below uses IProxiableInterface to enforce.
Here's some sample code that all appears fine except for this problem:
Without the parent class, Rider complains "'T': type name expected"
With the parent class, Rider says "'T': interface name expected".
For both, the compiler says "error CS0689: Cannot derive from 'T' because it is a type parameter"
Both of them allow the concrete proxy to fail to implement the interface.
abstract class AbstractProxy<T> : /*MonoBehaviour,*/ T // <-- Error: "'T': type name expected" or "'T': interface name expected"
where T : IProxiableInterface
{
protected T impl;
public AbstractProxy(T impl) {
this.impl = impl;
}
}
interface IProxiableInterface {}
interface IFriendly : IProxiableInterface {
string sayHi();
}
sealed class HiSayer : IFriendly {
public string sayHi() => "Hi";
}
sealed class HiProxy : AbstractProxy<IFriendly> {
public HiProxy(IFriendly impl) : base(impl) {}
public string sayHi() => impl.sayHi(); // <-- _should_ be an error when omitted but not because the interface constraint is ignored
}
sealed class User {
public User() {
IFriendly friendlyToBeProxied = new HiSayer();
IFriendly friendlyProxy = new HiProxy(friendlyToBeProxied);
Console.WriteLine(friendlyProxy.sayHi());
}
}
So it seems C# disallows this approach (which I learnt after typing all of this into StackOverflow and getting hinted with this question :) ).
For now I've had to remove the constraint on AbstractProxy so it doesn't have to implement the interface. As a workaround I've added an assertion to a factory method that takes an extra generic type indicating the type being built:
Assert.IsTrue(typeof(T1).IsAssignableFrom(typeof(T2)), "T2 \"{1}\" must implement T1 \"{2}\" for {0}", go, typeof(T2), typeof(T1));
So what's a better solution The Right Way to solve this, please?
This is the kind of scenario that requires meta-programming; specifically, you need to implement a specific interface only known at runtime, which isn't something you can express against a pre-compiled type. Typically, you would end up using TypeBuilder to create a new type at runtime, implementing the type you need, and then using reflection to inspect the interface you want looking for the members you need, adding those onto your new type (MethodBuilder etc), and writing an implementation (ILGenerator) that invokes whatever proxy logic you need (which may involve writing a constructor via ILGenerator that takes the proxy instance as a parameter and stores it in a field, then access the field in each method for the proxy step). You'd then create the concrete type, and store that somewhere as a cache (because all this TypeBuilder work is expensive). This is a lot of work! As a starting point: here's the proxy emitter for protobuf-net.Grpc
Looks like you want your AbstractProxy to use composition rather than inheritance, so you don't need it to derive from anything:
abstract class AbstractProxy<T> where T : IProxiableInterface
{
protected T impl;
public AbstractProxy(T impl)
{
this.impl = impl;
}
}
IProxiableInterface defines no behaviour so it seems that you are using it simply to constrain the generic types.
This would then be fine:
sealed class HiProxy : AbstractProxy<IFriendly>
{
public HiProxy(IFriendly impl) : base(impl) {}
public string sayHi() => impl.sayHi();
}

C# user defined exception

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.

Are virtual members called via reflection (in normal circumstances)?

I was testing the effects of calling a virtual member in a constructor, and discovered that when calling that member the resulting exception was wrapped within a TargetInvocationException.
According to the docs this is:
The exception that is thrown by methods invoked through reflection
However I'm unaware of any invokations via reflection. So does this mean virtual members are always called via reflection? If not why is it so in this case?
The code:
class ClassA
{
public ClassA()
{
SplitTheWords();
}
public virtual void SplitTheWords()
{
//I've been overidden
}
}
class ClassB : ClassA
{
private readonly String _output;
public ClassB()
{
_output = "Constructor has occured";
}
public override void SplitTheWords()
{
String[] something = _output.Split(new[]{' '}); //TargetInvocationException!
}
}
No, virtual methods are called via virtual dispatch.
Reflection is not being used here. And nor is it for any virtual method calls. I believe the documentation for the exception is slightly misleading in that exceptions of this type are thrown by methods invoked via reflection, however not exclusively so.
If anyone is curious as to why the code in the question gives an exception, it is because of the order in which the constructors are executed. The ClassB constructor is the same as:
public ClassB() : base()
{
_output = "Constructor has occured";
}
Note the call to base(), this calls the base constructor before the ClassB constructor is run and, hence, before _output is assigned. The SplitTheWords virtual method is called in the base constructor, which resolves to ClassB.SplitTheWords. This method attempts to use _output, hence the error.
For a more detailed look at why virtual methods should not be called from constructors this SO question has some useful information. Eric Lippert also has a very good blog post on why this is the case here.
Are virtual members called via reflection (in normal circumstances)?
NO.
Nor from a constructor, so something else is going on. It would help to see the code calling the code you have shown and the stack trace from the exception.

Force attribute usage in subclass of abstract superclass

How can I force a subclass to implement certain Attributes of its superclass? The reason is that I want to use Attributes for general information about the class, e.g. "DisplayName", "Description" or "Capabilities".
So I thought I might implement them in a superclass and force the subclasses to implement the attributes.
Is there something like an abstract attribute like for methods?
[abstract DeclareMe]
public abstract class InheritMe {
public abstract void DeclareMe();
}
As your class must be run sooner or later, you can add checking mechanism to your base class to verify the existance of certain attributes in your sub classes.
Here's some sample code for you.
class Program
{
static void Main(string[] args)
{
var a = new SubA();
var b = new SubB();
}
}
class BaseClass
{
public BaseClass()
{
Type t = GetType();
if (t.IsDefined(typeof(SerializableAttribute), false) == false)
{
Console.WriteLine("bad implementation");
throw new InvalidOperationException();
}
Console.WriteLine("good implementation");
}
}
[Serializable]
class SubA : BaseClass
{ }
class SubB : BaseClass
{ }
The last word, don't be too wary of yourself. Once I was doing my design, I always thought I might call two methods in a wrong order or forget to do something, then I turned a simple design into a complicated one to prevent my possible mistakes. Later I threw away the guards, just throwing Exceptions and the code used to detect unexpected situations were surrounded by #if DEBUG.
In addition to the answers from that other thread:
You could use FxCop and implement a custom rule that checks if your attributes are present.

Categories

Resources