【问题标题】:How to prevent shadowing and promote given method?如何防止阴影和促进给定的方法?
【发布时间】:2012-12-10 12:23:16
【问题描述】:

在 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

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

【问题讨论】:

  • 推广是什么意思?你打算发生什么?让bar.print 覆盖foo.print
  • 这不是超载吗?在 foo 中你需要一个接受对象的打印方法吗?

标签: c# inheritance shadowing


【解决方案1】:

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

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

这将调用bar 上定义的方法,尽管foo 上的方法会有一个更匹配类型的参数。
这里发生的情况如下:编译器在 bar 上找到一个具有正确名称(“print”)、正确数量的参数(1)和传入参数可转换为的参数类型的方法(@987654327 @ 可以转换为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
        }
    }
    

【讨论】:

  • 您不必解释什么是阴影 :-) 我知道它是什么。您的两个解决方案在技术上都是正确的(谢谢),但是它们是不可行的。第一个原因很明显——调用者必须牢记整个继承树(这很容易出错)。第二个涉及很多技巧 - 将其与 bar 定义中的 C++ using foo.print 进行比较,这让我进一步了解其他方法。
  • @greenoldman:我刚刚更新了我的答案 - 请查看有关如何解决它的想法。
  • 同时我使用了相同的构造:-)。我会将这个问题保持一段时间(以吸引其他读者),如果没有更好的出现,我会接受你的回答。我希望你没事。
  • @greenoldman:我认为您不会找到比上面显示的 public new void print(string s) 更简单的解决方案。
猜你喜欢
  • 2011-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-06
  • 1970-01-01
  • 1970-01-01
  • 2013-02-25
  • 2018-07-19
相关资源
最近更新 更多