Every type inherits directly or indirectly from System.Object, so each has an Equals method. This includes both value types (which inherit from System.ValueType) and reference types (which inherit from System.Object).

public virtual bool Equals(Object object);

The Equals method returns true if the object passed in to the method is equal to the object on which the method was called.

System.Object includes a default implementation of the Equals method that :

For value types, returns true if the underlying values are the same (even though there are two copies of the value)

For reference types, returns true if the references refer to the exact same object in memory

You can overload any of the following binary operators: +, -, *, /, %, &, |, ^, <<, >>. A binary operator is an operator applied to two operands.

For example, assume we have a Dog class that has the following bool properties: BarksALot, LikesBalls and Sheds. We might implement the & operator for the Dog class so that we get a new Dog instance with all of the boolean properties AND’d together.

In C#, an operator is a symbol that defines some operation that should take place when evaluating an expression.

For example, the plus sign (+) is an operator that is typically used to add two numbers, or two instances of a class.

int a = 5 + 6; // 11
string s = "Corn" + "dog"; // Corndog

For most operators, if you try using them on instances of a class that you define, the operator will have no meaning and you’ll get a compile-time error. (With the exception of the equality (==) and inequality (!=) operators, which are automatically defined for every type).

If you want a particular operator to make sense for instances of a class that you define, you can define that operator as a member of your class. For example, I could define the plus (+) operator for the Dog class, such that it merges the dog’s names and adds their ages.

When you use the event keyword to define an event, the compiler automatically creates a private backing variable that is a delegate instance, as well as code that encapsulates adding and removing methods to the delegate’s invocation list.

public event EventHandler Barked;

You can also explicitly declare the backing variable and the add/remove accessors. The following code results in equivalent behavior to the code shown above.