2

在 C++ 中,它是通过“使用”完成的,而在 C# 中呢?

public class foo
{
   public void print(string s) {...}
}

public class bar : foo
{
   // shadowing
   public void print(object o) {...}
}

如何提升foo.print,所以foo.printbar.print编译器的“级别”相同(bar当然)?

更新 1

最初我添加了一段关于阴影和覆盖之间常见混淆的段落,但后来我删除了它,因为我认为它会冒犯读者。

阴影就像跨越继承树的重载。阴影不是压倒一切的。

更新 2

foo.print解决重载方法时不再考虑后阴影print。提升foo.print会让它重新进入流程——所以当我调用bar_object.print("hello")该方法时,它foo.print会被调用。

4

1 回答 1

3

在您的具体示例中,bar.print(object)确实“阴影”更具体foo.print(string)

new bar().print("i am a string");

这将调用定义在 on 上bar的方法,尽管 on 方法foo会有一个更好地匹配类型的参数。
这里发生的情况如下:编译器找到一个bar具有正确名称(“print”)、正确数量的参数(1)和传入参数可转换为的参数类型(string可以转换为object)的方法.
因此,编译器没有理由进一步查找继承链。

据我所知,没有类似于 C++ 的using.
如果要使用基类上定义的方法,基本上有三种选择:

  1. 在调用方:将bar实例转换为foo

    var bar = new bar();
    var foo = (foo)bar;
    foo.print("i am a string"); // Will call foo.print(string)
    
  2. 在 calee 方面:内部bar.print(object)检查传递参数的类型:

    public void print(object o)
    {
        var s = o as string;
    
        if(s != null)
            base.print(s);
        else
        {
            // Other code.
        }
    }
    
  3. 这将最接近 C++ using:实际上覆盖或隐藏派生类中的原始方法:

    public class bar : foo
    {
        public new void print(string s)
        {
            base.print(s);
        }
    
        public void print(object o)
        {
            // some code
        }
    }
    
于 2012-12-10T12:36:41.880 回答