Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Abstract class inheriting the most derived type

Unfortunatly, i can't find the original project which led me to this question. That would have perhaps given this question a bit more context.

EDIT: I found the original project i've seen this in: http://mews.codeplex.com/SourceControl/changeset/view/63120#1054567 with a concrete implementation at: http://mews.codeplex.com/SourceControl/changeset/view/63120#1054606

Lets say i have an abstract class with a concrete implementation that does something usefull like:

abstract class AbstractClass
{
    public virtual int ConvertNumber(string number)
    {
        string preparedNumber = Prepare(number);
        int result = StringToInt32(number);
        return result;
    }

    protected abstract string Prepare(string number);

    protected virtual int StringToInt32(string number)
    {
        return Convert.ToInt32(number);
    }
}

sealed class ConcreteClass : AbstractClass
{
    protected override string Prepare(string number)
    {
        return number.Trim();
    }

    public override int ConvertNumber(string number)
    {
        return base.ConvertNumber(number);
    }
}

This is as basic as it gets. Now in the code i've seen on the web the author implemented inheritence by inheriting the Abstract class from the most derived type, e.g:

abstract class AbstractGenericClass<TGenericClass>
    where TGenericClass : AbstractGenericClass<TGenericClass>
{
    public virtual int ConvertNumber(string number)
    {
        string preparedNumber = Prepare(number);
        int result = StringToInt32(number);
        return result;
    }

    protected abstract string Prepare(string number);

    protected int StringToInt32(string number)
    {
        return Convert.ToInt32(number);
    }
}

sealed class ConcreteGenericClass : AbstractGenericClass<ConcreteGenericClass>
{
    protected override string Prepare(string number)
    {
        return number.Trim();
    }

    public override int ConvertNumber(string number)
    {
        return base.ConvertNumber(number);
    }
}

Now why would one do such a thing? I very vaguely remember this was a technique heavily used in ATL for performance reasons (some way of calling concrete member implementations without working with a vtable?) I'm not very sure on this part.

I've checked the generated IL for both cases and they are exactly the same.

Who can explain this to me?

like image 481
Polity Avatar asked Oct 09 '22 23:10

Polity


1 Answers

That is a C# version of what is called the Curiously Recurring Template Pattern in C++. It is a bit weird, and personally, I try to avoid it. It is useful, but I find it more confusing than useful.

See my article for details:

http://blogs.msdn.com/b/ericlippert/archive/2011/02/03/curiouser-and-curiouser.aspx

like image 112
Eric Lippert Avatar answered Oct 14 '22 01:10

Eric Lippert