Method marked as Protected internally can be accessed by the Classes within the same assembly, and classes derived from the declaring class.


Make sure your C# code conforms to the Common Language Subset (CLS). To help with this, add the [assembly:CLSCompliant(true)] global attribute to your C# source files. The compiler will emit an error if you use a C# feature which is not CLS-compliant.


Yes, using the params keyword. The arguments are specified as a list of arguments of a specific type, e.g. int. For ultimate flexibility, the type can be object. The standard example of a method which uses this approach is System.Console.WriteLine().


This is the subject of some debate, and is partly a matter of taste. However, it is accepted by many that exceptions should be thrown only when an ‘unexpected’ error occurs. How do you decide if an error is expected or unexpected? This is a judgement call, but a straightforward example of an expected error is failing to read from a file because the seek pointer is at the end of the file, whereas an example of an unexpected error is failing to allocate memory from the heap.


Only instances of the System.Exception classes, or classes derived from System.Exception. This is in sharp contrast with C++ where instances of almost any type can be thrown


Yes, in fact exceptions are the recommended error-handling mechanism in C# (and in .NET in general). Most of the .NET framework classes use exceptions to signal errors.


A C# destructor is really just an override of the System.Object Finalize method, and so is virtual by definition.


Yes, but it’s generally not a good idea. The mechanics of object construction in .NET are quite different from C++, and this affects virtual method calls in constructors.

C++ constructs objects from base to derived, so when the base constructor is executing the object is effectively a base object, and virtual method calls are routed to the base class implementation. By contrast, in .NET the derived constructor is executed first, which means the object is always a derived object and virtual method calls are always routed to the derived implementation. (Note that the C# compiler inserts a call to the base class constructor at the start of the derived constructor, thus preserving standard OO semantics by creating the illusion that the base constructor is executed first.)

The same issue arises when calling virtual methods from C# destructors. A virtual method call in a base destructor will be routed to the derived implementation.


Use the abstract modifier on the method. The class must also be marked as abstract (naturally). Note that abstract methods cannot have an implementation (unlike pure virtual C++ methods).


No. Like C++, methods are non-virtual by default, but can be marked as virtual.