如何防止阴影和推广给定的方法?

时间:2012-12-10 12:23:17

标签: c# inheritance shadowing

在C ++中,它使用“using”和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

最初我添加了一个关于阴影和覆盖之间常见混淆的段落,但之后我将其删除了,因为我认为这会让读者反感。

阴影就像跨越继承树的重载一样。阴影 NOT 覆盖。

更新2

在解析重载方法foo.print时,不再考虑投影print。推广foo.print会使其恢复正常 - 因此,当我致电bar_object.print("hello")时,系统会调用方法foo.print

1 个答案:

答案 0 :(得分:3)

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

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

这会调用bar上定义的方法,尽管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
        }
    }