8

I have this code written by another programmer and I cant get my head around it

public abstract class AppBase<T> : IApp where T : AppBase<T>, new()
{
    //
}

From my understanding the AppBase class of type T implements the interface IApp where T implements ???

Can some one explain the last part?

Quality Catalyst
  • 6,531
  • 8
  • 38
  • 62
Abhi.Net
  • 722
  • 3
  • 11
  • 37

1 Answers1

7

The constraint on T in this case means that T must implement AppBase<T> and have a default constructor. Effectively, you need to pass yourself as the type.

This is usually done as an attempt to workaround the type system and provide access to the implementing type within the base class via typeof(T). For example, given:

public interface IApp {}

public abstract class AppBase<T> : IApp where T : AppBase<T>, new()
{
    public void Print()
    {
        Console.WriteLine(typeof(T).ToString());
    }
}

public class AppBaseFoo : AppBase<AppBaseFoo>
{
}

You can then write code like:

var foo = new AppBaseFoo();
foo.Print();

Which will print the type information for AppBaseFoo. However, this isn't foolproof - for example, subclassing "breaks" this. Adding:

public class AppBaseBar : AppBaseFoo {}

And then writing:

var bar = new AppBaseFoo();
bar.Print();

Causes the same AppBaseFoo information to be printed.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • Put slightly more simply: "enforces that `T` is a concrete type of the abstract `AppBase`". +1 for the really good explanation including *why* someone would do this. – CodingWithSpike Mar 29 '16 at 22:46
  • @Reed Copsey: Thank you for your answer, You have explained the code very well but I am still confused as to what the use of such pattern is? – Abhi.Net Mar 29 '16 at 22:47
  • @Abhi.Net really, I'd suggest avoiding it. It's usually an attempt to try to access the subclass type information from the base class, which is typically not a good idea... – Reed Copsey Mar 29 '16 at 22:49
  • @Reed Copsey: It does make a lot more sense now so I have marked your answer as my accepted answer. I am still going through the code and it looks like the other programmer was trying to implement the singleton pattern using this. This code is used in our base class for the application so cant really ignore it. – Abhi.Net Mar 29 '16 at 22:53
  • @Abhi.Net This is definitely not the right way to create a singleton - so I'd look at it carefully. – Reed Copsey Mar 29 '16 at 22:55
  • @Reed Copsey: Finally found this in the comments. http://stackoverflow.com/questions/16745629/how-to-abstract-a-singleton-class/16745753#16745753. Still not sure about the intention but I'll go through the link and see what this achieves. Thank you again for all your help. Much appreciated. – Abhi.Net Mar 29 '16 at 22:58
  • @Abhi.Net I'd suggest rewriting to use a real singleton, using `Lazy` - far safer, not much code, and *much* cleaner (and no way to violate the singleton rules) – Reed Copsey Mar 29 '16 at 23:05