Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Inheritance inversion

0.00/5 (No votes)
4 Jan 2015 1  
Abstract class inheritance inversion where in the base class calls the inheriting class.

Introduction

While developing a WPF application the problem of providing static code generated elements for ComboBox, ListBox and even DataGrid came up. This article presents a Generics way to hide functionality in an abstract class or real class that relies on actions taken in the inheriting class.

Using the code

In this case I opted for an abstract class. The implementation below is to provide the All function to all inheriting classes. This assumes we are sovling a problem revolving round classes derived from List<>. What this code does is to pass the type of the inheriting class to the class it is inheriting from. This has interesting implications as seen below and is in a way a circular reference in inhertance terms.

C#
 /// <summary>
 /// Abstract class for classes providing static Lists binding to connection
 /// based WPF GUI elements such as ComboBox, ListBox, DataGrid...
 /// </summary>
 /// <typeparam name="T">The Type contained in the list</typeparam>
 /// <typeparam name="I">The Type of the inheriting class</typeparam>
 public abstract class AbstractSingletonList<T, I> : List<T>
 {
     /// <summary>
     /// The list variable to implement singleton behaviour.
     /// </summary>
     private static I _list;

     /// <summary>
     /// Arbitrary lock object for the static All getter below to prevent
     /// any race conditions for this singleton.
     /// </summary>
     private static object _lockObject = new object();

     /// <summary>
     /// Get all objects in this list in a Singleton pattern.
     /// This invokes the child object. As I've set it up here
     /// only the constructor is called from a static metod.
     /// </summary>
     public static I All
     {
         get
         {
             if (_list == null)
             {
                 lock (_lockObject)
                 {
                     if (_list == null)
                     {
                         Type t = typeof(I);
                         ConstructorInfo ci = t.GetConstructor(new Type[] {});
                         object o = ci.Invoke(new object[] {});
                         _list = (I)o;
                     }
                 }
             }
             return _list;
         }
     }
}

The inheriting class then looks like this:

C#
public class WeekDaysChron : AbstractSingletonList<Day, WeekDaysChron>
{
    public WeekDaysChron()
    {
        Add(new Day("Any", "*"));
        Add(new Day("Monday", "mon"));
        Add(new Day("Tuesday", "tue"));
        Add(new Day("Wednesday", "wed"));
        Add(new Day("Thursday", "thu"));
        Add(new Day("Friday", "fri"));
        Add(new Day("Saturday", "sat"));
        Add(new Day("Sunday", "sun"));
    }
}

 

The code above does contain hard coded values but they could just as well have originated from EF6 or XML or from elsewhere. What is intersting here is how clean the code becomes. It rather shows that even static stuff can be hidden in the base class with access to things in the inheriting class.

The lists ref below simplly points at the namespace in the current assembly where these classes above reside. In this case that is the definition within the top level wpf tag in question:

xmlns:lists="clr-namespace:WinOrbiter.Entities.Lists"

While this may sound like a gymick it greatly simplifies things in WPF is as seen below:

<ComboBox
    ItemsSource="{Binding Source={x:Static lists:WeekDaysChron.All}}"
    SelectedItem="{Binding DayOfWeek}"
/>

To keep things simple for this illustration I did define ToString for the Day class but other WPF tricks are available to handle that in a more sophisticated way.

The attributes defined and set in the Day class are completely arbitrary and and up to project spec and include what ever variety of information. The above code binds and sets the entire object on the ComboBox selection which I find quite useful when using NewtonSoft.Json to serialize.

Points of Interest

I found it quite interesting getting away with invoking the class that is inheriting right from the base class from a static method. It is a weird and wonderful addition to the toolbox which my thought process had not included until I tried this.

History

Initial version 1.0.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here