This week a work more focused on reviewing some of the advanced topics of C#, starting from collections, handling of exceptions, delegates, and, events.
Generics and Non-generic Collections
There are 2 types of collections you can use in C# that are generic and non-generic.
The main difference is that you use the type <T> generic to denote which type of variable the collection should store.
For example, you can have a Non-generic LIST, which can contain strings, ints, floats, etc.
But if you declare a generic LIST<int> you can only store integers in that list.
In most cases, it is recommended to use generic collections because they perform faster than non-generic collections and minimize exceptions by giving compile-time errors.
Personally, I didn’t knew until now about the existence of the non-generic collects, despite the fact that generics are more recommendable, there can be some cases where it is better to use non-generics.
Built In Exceptions
Exceptions are pretty the same in every programming language, but knowing the types of exceptions that you can throw is better for the future and self-documentation of the software.
Having proper messages and types of exceptions can facilitate the debugging of code and also determine what’s going on.

But you also, if you require, can create your own classes of exceptions, Microsoft recommends deriving custom exception classes from the Exception class.
Delegates
What if we want to pass a function as a parameter?
The delegate is a reference type of data that defines the method signature.
A delegate can be declared using the DELEGATE keyword followed by a function signature:
public delegate void MyDelegate ([params])
The delegate can point to multiple methods, this is called a multicast delegate.
Events – Publishers & Subscribers
An event is a notification sent by an object to signal the occurrence of an action.
Event in .NET follows the observer design pattern.
The class that raises events is called publisher, and the class that receives the notification is called subscriber.
.NET Framework includes built-in delegate types EventHanlder and EventHandler<TEventParams> for the most common events.

To create an event you need to declare it first in the publisher class.
public event EventHandler MyEvent<bool>():
And then call it when you want to send the “notification”:
MyEvent?.Invoke(this, true);
In this example, the event is sending a param that is a boolean.
If you want to pass more than one value as event data, then create a class deriving from the EventArgs base class.