Why is this generic method invoking a base class method and not a derived class method?

For the following code:

class B { public String G() { return "BG()"; } } class D : B { public String G() { return "DG()"; } } class TestCompile { private static String TestG<T>(T b) where T: B { return bG(); } static void Main(string[] args) { TestG(new D()); } } 

The result is BG() , while the result of similar C ++ code will be DG() .

Why is there such a difference?

+6
source share
4 answers

C # generators compile only once: at compile time generic. (Think about it: C # allows you to use List<T> without seeing its implementation.) Here, he sees from the where T: B clause that the parameter is B , so he calls BG .

C ++ templates are compiled every time they are called. When you enter TestG<D>() , a new copy of TestG will be compiled with T = D During the call, the compiler sees that D has its own method G and calls it.

C ++ - the equivalent of C # generic would be

 template<typename T> string TestG(T t) { B& b = static_cast<B&>(t); // force `t` into a `B` return bG(); } 

Others' comments regarding the use of virtual apply equally to C # and C ++. I just explain why C ++ behaves differently than C #.

+6
source

Use the override keyword:

 class B { public virtual String G() { return "BG()"; } } class D : B { public override String G() { return "DG()"; } } 

Without the keyword override, the inherited method does not replace the base one.

Without redefinition:

 D obj = new D(); obj.G(); // "DG()" ((B)obj).G(); // "BG()" 

Override:

 D obj = new D(); obj.G(); // "DG()" ((B)obj).G(); // "DG()" 
+9
source

If you did not note that you marked BG as virtual and DG as override .

You have a compiler warning:

CS0108: 'DG ()' hides an inherited BG () element. Use a new keyword if you needed to hide.

but you decided to ignore it. I would expect the best from a C ++ developer! :)

+3
source

This is because the parameter b is in type b ref. if you press b on D , it will call a function in D

0
source

Source: https://habr.com/ru/post/902643/