Deep C# - Inheritance
Written by MIke James   
Monday, 27 December 2021
Article Index
Deep C# - Inheritance
Inherited Constructors
Is and As

Inheritance - is it where it all goes wrong? Find out in this extract from my new book, Deep C#: Dive Into Modern C#.

Deep C#

 Buy Now From Amazon


 Chapter List

  1. Why C#?

    I Strong Typing & Type Safety
  2. Strong Typing
    Why Strong Typing
  3. Value & Reference
  4.    Extract Value And Reference
  5. Structs & Classes
    Structs & Classes 
  6. Inheritance
  7. Interfaces & Multiple Inheritance
    Extract Interface
  8. Controlling Inheritance
    II Casting & Generics
  9. Casting - The Escape From Strong Typing
    Extract Casting I ***NEW!
  10. Generics
  11. Advanced Generics
  12. Anonymous & Dynamic
    III Functions
  13. Delegates
  14. Multicast Delegates
  15. Anonymous Methods, Lambdas & Closures
    IV Async
  16. Threading, Tasks & Locking
  17. The Invoke Pattern
  18. Async Await
  19. The Parallel For
    V Data - LINQ, XML & Regular Expressions
  20. The LINQ Principle
  21. XML
  22. LINQ To XML
  23. Regular Expressions
    VI Unsafe & Interop
  24. Interop
  25. COM
  26. Custom Attributes
  27. Bit Manipulation
  28. Advanced Structs
  29. Pointers 

Extra Material




Inheritance is a simple idea, until you try to make use of it. What's a virtual method? How do you use override and new? It’s tricky when you look at the details. There are also all of the philosophical issues about what makes good maintainable code. In this chapter we look at the basics of inheritance and the subtle corners of the idea.

Simple Inheritance

C#’s inheritance mechanisms are particularly clean and easy, but let’s make sure that we know how they work.

The fundamental class declaration in C# takes the form:

class name: baseclass

If you don’t specify a base class then the default class called object is used.

Only a class can inherit and only from another class – structs always inherit from object and can’t be used to create new structs or classes by inheritance. If you want to create a class that can’t be used as a base class for a new class then simply add the sealed modifier to the start of the class definition – see Chapter 7.

Notice that C# only allows single inheritance which, by contrast to C++ and Python, is something of a relief! If you think that C++’s ability to create classes from more than one base class is a good idea then you haven’t seen some of the stranger things that can happen when this powerful facility gets out of hand. The preferred approach to multiple inheritance is to make use of interfaces which define the type of what is to be inherited without supplying an implementation. There is no doubt that single inheritance is safer and can do everything that multiple inheritance can if you are prepared to approach it in the right way and do some additional work.

Variable Type and Object Type

As we have already seen, when you create an instance of a class you first create a reference variable of the correct type. For example:

class MyClassA {};
MyClassA MyA;

doesn’t create an instance of MyClassA - only a reference variable capable of pointing to an object of type MyClassA. You have to be careful how you phrase such ‘pointing to an object’ because C# doesn’t have pointers as such.

After declaring a reference variable you can set it to point to, or reference, a new instance of the class using:

MyA = new MyClassA();

or putting this together:

MyClassA MyA = new MyClassA();

Notice that there are two things going on here – the type of the variable making the reference and the type of the object it references. In a simple world these would always be the same.

If you now create a class that inherits from MyClassA:

Class MyClassB:MyClassA;

then any instance of MyClassB starts out with all of the methods defined in the definition of MyClassA. This is what inheritance is all about - code reuse. If class MyClassA has a show method then so now does class MyClassB and without you having to write a single line of code. 

Notice that this means that class MyClassB has two types of method - those that are defined as part of MyClassA and those that are defined within it. 

If you simply want to use the inherited methods of class MyClassB you can simply use them as if they were "native" to MyClassB.

For example:

MyClassBMyB = new MyClassB();;

results in the show method defined in class MyClassA being called. 

There is one small complication - what if the methods of class MyClassB need to call the methods defined in class MyClassA? One of the advantages of single inheritance is that if you want to call the base class’s methods you can do so with a single keyword base because you don't have to specify which base class is to be used as there is only one. For example, if MyClassB inherits a method “show” from MyClassA then MyClassB can call the method using:;

In practice you can omit base as long as there is no ambiguity, i.e. if MyClassB doesn't have a show method. 

Last Updated ( Saturday, 01 January 2022 )