继承最派生类型的抽象类
不幸的是,我找不到导致我提出这个问题的原始项目。这或许会给这个问题更多的背景。
编辑:我找到了我在其中看到的原始项目: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 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 中大量使用的技术(在不使用 vtable 的情况下调用具体成员实现的某种方式?)我对此部分不太确定。
我检查了这两种情况生成的 IL,它们是完全相同的。
谁能给我解释一下这个?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是 C++ 中所谓的奇怪重复模板模式的 C# 版本。这有点奇怪,就我个人而言,我尽量避免它。它很有用,但我发现它比有用更令人困惑。
有关详细信息,请参阅我的文章:
http:// /blogs.msdn.com/b/ericlippert/archive/2011/02/03/curiouser-and-curiouser.aspx
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