[英]Why does this generic method call the base class method, not the derived class method?
For the following code: 对于以下代码:
class B
{
public String G() { return "B.G()"; }
}
class D : B
{
public String G() { return "D.G()"; }
}
class TestCompile
{
private static String TestG<T>(T b) where T: B
{
return b.G();
}
static void Main(string[] args)
{
TestG(new D());
}
}
The result is BG()
, whereas the result of similar C++ code would be DG()
. 结果是BG()
,而类似的C ++代码的结果将是DG()
。
Why is there this difference? 为什么会出现这种差异?
Use the override keyword: 使用override关键字:
class B
{
public virtual String G() { return "B.G()"; }
}
class D : B
{
public override String G() { return "D.G()"; }
}
Without the override keyword, the inherited method doesn't replace the base one. 如果没有override关键字,则继承的方法不会替换基本方法。
Without override: 没有覆盖:
D obj = new D();
obj.G(); // "D.G()"
((B)obj).G(); // "B.G()"
With override: 使用覆盖:
D obj = new D();
obj.G(); // "D.G()"
((B)obj).G(); // "D.G()"
C# generics are compiled only once: at the time the generic is compiled. C#泛型只编译一次:编译泛型时。 (Think about it: C# lets you use List<T>
without seeing its implementation.) Here, it sees from the where T: B
clause that the parameter is a B
, so it calls BG
. (考虑一下:C#允许你使用List<T>
而不看其实现。)这里,它从where T: B
看到where T: B
子句参数是B
,所以它调用BG
。
C++ templates are compiled each time they are invoked. 每次调用C ++模板时都会编译它们。 When you type TestG<D>()
, a brand new copy of TestG
is compiled with T = D
. 当您键入TestG<D>()
,将使用T = D
编译一个全新的TestG
副本。 At invocation time, the compiler sees that D
has its own G
method and calls it. 在调用时,编译器会看到D
有自己的G
方法并调用它。
The C++ equivalent of the C# generic would be C#generic的C ++等价物
template<typename T>
string TestG(T t)
{
B& b = static_cast<B&>(t); // force `t` into a `B`
return b.G();
}
The remarks of others regarding the use of virtual
apply equally to C# and C++. 其他人关于virtual
使用的评论同样适用于C#和C ++。 I'm just explaining why C++ behaves differently from C#. 我只是在解释为什么C ++与C#的行为不同。
Becuase you've neglected to mark BG
as virtual
, and DG
as override
. 因为你忽略了将BG
标记为virtual
,而将DG
标记为override
。
You got this compiler warning: 你有这个编译器警告:
CS0108: 'DG()' hides inherited member 'BG()'. CS0108:'DG()'隐藏继承的成员'BG()'。 Use the new keyword if hiding was intended. 如果要隐藏,请使用new关键字。
but you chose to ignore it. 但你选择忽略它。 I would expect better from a C++ developer! 我希望C ++开发人员能做得更好! :) :)
It's because the parameter b
is in a B
type ref. 这是因为参数b
是B
型ref。 if you cast b
to D
it'll call the function on D
. 如果你将b
为D
它将调用D
上的函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.