为什么这个泛型方法调用基类方法,而不是派生类方法?

CPW*_*CPW 6 c# generics

对于以下代码:

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());
    }
}
Run Code Online (Sandbox Code Playgroud)

结果是B.G(),而类似的C++代码的结果将是D.G().

为什么会出现这种差异?

Kev*_*sse 9

使用override关键字:

class B
{
    public virtual String G() { return "B.G()"; }
}

class D : B
{
    public override String G() { return "D.G()"; }
}
Run Code Online (Sandbox Code Playgroud)

如果没有override关键字,则继承的方法不会替换基本方法.

没有覆盖:

D obj = new D();
obj.G(); // "D.G()"
((B)obj).G(); // "B.G()"
Run Code Online (Sandbox Code Playgroud)

使用覆盖:

D obj = new D();
obj.G(); // "D.G()"
((B)obj).G(); // "D.G()"
Run Code Online (Sandbox Code Playgroud)

  • 那么,如果你不是用C#方式做的话,使用C#有什么意义呢?:p (2认同)

Ray*_*hen 6

C#泛型只编译一次:编译泛型时.(考虑一下:C#允许你在List<T>不看其实现的情况下使用.)在这里,它从where T: B子句中看到参数是a B,所以它调用B.G.

每次调用C++模板时都会编译它们.当您键入时TestG<D>(),TestG会编译一个全新的副本T = D.在调用时,编译器会看到它D有自己的G方法并调用它.

C#generic的C++等价物

template<typename T>
string TestG(T t)
{
    B& b = static_cast<B&>(t); // force `t` into a `B`
    return b.G();
}
Run Code Online (Sandbox Code Playgroud)

其他人关于使用的评论virtual同样适用于C#和C++.我只是在解释为什么C++与C#的行为不同.