Абстрактный класс, наследующий наиболее производный тип - PullRequest
5 голосов
/ 20 сентября 2011

К сожалению, я не могу найти оригинальный проект, который привел меня к этому вопросу.Возможно, это дало бы этому вопросу немного больше контекста.

РЕДАКТИРОВАТЬ: Я нашел оригинальный проект, в котором я видел это: http://mews.codeplex.com/SourceControl/changeset/view/63120#1054567 с конкретной реализацией по адресу:http://mews.codeplex.com/SourceControl/changeset/view/63120#1054606

Допустим, у меня есть абстрактный класс с конкретной реализацией, который делает что-то полезное:

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);
    }
}

Это настолько просто, насколько это возможно.Теперь в коде, который я видел в Интернете, автор реализовал наследование, унаследовав класс Abstract от самого производного типа, например:

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);
    }
}

Теперь, почему кто-то должен делать это?Я очень смутно помню, что этот метод активно использовался в ATL по соображениям производительности (какой-то способ вызова конкретных реализаций-членов без работы с виртуальной таблицей?) Я не очень уверен в этой части.

Я проверялсгенерированный IL для обоих случаев, и они абсолютно одинаковы.

Кто может мне это объяснить?

1 Ответ

4 голосов
/ 20 сентября 2011

Это версия C # того, что называется Curily Recurring Template Pattern в C ++.Это немного странно, и лично я стараюсь избегать этого.Это полезно, но я нахожу это более запутанным, чем полезным.

Подробности см. В моей статье:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...