简体   繁体   English

继承最派生类型的抽象类

[英]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 编辑:我发现原始项目我已经看到了这个: http//mews.codeplex.com/SourceControl/changeset/view/63120#1054567 ,具体实现在: http//mews.codeplex.com/SourceControl /变更/视图/ 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, eg: 现在在我在网上看到的代码中,作者通过从最派生类型继承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);
    }
}

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. 我非常清楚地记得这是ATL出于性能原因大量使用的一种技术(某种方式调用具体的成员实现而不使用vtable?)我不太确定这一部分。

I've checked the generated IL for both cases and they are exactly the same. 我已经检查了两种情况下生成的IL,它们完全一样。

Who can explain this to me? 谁能向我解释一下?

That is a C# version of what is called the Curiously Recurring Template Pattern in C++. 这是C ++中所谓的奇怪重复模板模式的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 http://blogs.msdn.com/b/ericlippert/archive/2011/02/03/curiouser-and-curiouser.aspx

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM