Click here to Skip to main content
15,867,308 members
Articles / Programming Languages / C# 4.0
Tip/Trick

Inheritance inversion

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
4 Jan 2015CPOL2 min read 13.7K   6   6
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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Iceland Iceland
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionHacky Pin
FatCatProgrammer12-Jan-15 4:20
FatCatProgrammer12-Jan-15 4:20 
AnswerRe: Hacky Pin
Thorvaldur Arnarson13-Jan-15 13:39
Thorvaldur Arnarson13-Jan-15 13:39 
GeneralRe: Hacky Pin
FatCatProgrammer13-Jan-15 16:10
FatCatProgrammer13-Jan-15 16:10 
GeneralRe: Hacky Pin
Thorvaldur Arnarson13-Jan-15 16:19
Thorvaldur Arnarson13-Jan-15 16:19 
GeneralRe: Hacky Pin
FatCatProgrammer14-Jan-15 2:40
FatCatProgrammer14-Jan-15 2:40 
It's not a functional difference. It's a bug Smile | :) Somewhere else in your code you can do this:
lockObject = new object();

Which then messes up your double locking pattern since two threads will be able to lock different objects.
Relativity

GeneralRe: Hacky Pin
Thorvaldur Arnarson13-Jan-15 16:39
Thorvaldur Arnarson13-Jan-15 16:39 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.