当前位置:  开发笔记 > 编程语言 > 正文

方法隐藏如何在C#中起作用?(第二部分)

如何解决《方法隐藏如何在C#中起作用?(第二部分)》经验,为你挑选了1个好方法。

打印以下程序

A:C(A,B)
B:C(A,B)

(正如它应该)

public interface I
{
    string A();
}

public class C : I
{
    public string A()
    {
        return "A";
    }

    public string B()
    {
        return "B";
    }
}

public class A
{
    public virtual void Print(C c)
    {
        Console.WriteLine("A:C(" + c.A() + "," + c.B() + ")");
    }
}

public class B : A
{
    public new void Print(C c)
    {
        Console.WriteLine("B:C(" + c.A() + "," + c.B() + ")");
    }

    public void Print(I i)
    {
        Console.WriteLine("B:I(" + i.A() + ")");
    }
}

class Program
{
    public static void Main(string[] args)
    {
        A a = new A();
        B b = new B();
        C c = new C();
        a.Print(c);
        b.Print(c);
    }
}

但是,如果我在B类中将关键字'new'更改为'override',如下所示:

    public override void Print(C c)

突然之间的程序开始打印:

A:C(A,B)
B:I(A)

为什么?



1> Jon Skeet..:

这与如何解决重载方法有关.

有效地(稍微简化),编译器首先查看表达式(B)的声明类型,并查找首先在该类型中声明的候选方法.如果有任何适当的方法(即所有参数都可以转换为方法的参数类型),那么它不会查看任何父类型.这意味着如果在派生类型中存在任何"新近声明的"适当方法,则初始声明在父类型中的重写方法不会获得查找.

这是一个稍微简单的例子:

using System;

class Base
{
    public virtual void Foo(int x)
    {
        Console.WriteLine("Base.Foo(int)");
    }
}

class Derived : Base
{
    public override void Foo(int x)
    {
        Console.WriteLine("Derived.Foo(int)");
    }

    public void Foo(double d)
    {
        Console.WriteLine("Derived.Foo(double)");
    }
}

class Test
{
    static void Main()
    {
        Derived d = new Derived();
        d.Foo(10);
    }
}

这版画Derived.Foo(double)-即使编译器知道有型的参数的匹配方法int,和参数的类型int,并将其从转换intint从比转换"更好" intdouble,只有事实Foo(double)的方法最初宣布Derived表示编译器忽略Foo(int).

这是非常令人惊讶的IMO.我可以看到为什么它会是如果案件Derived没有重载Foo-否则将在基类一个新的,更具体的,方法可能会意外更改的行为-但显然Derived这里知道有关Base.Foo(int),因为它的覆盖它.这是(相对较少)的一点,我认为C#设计师做出了错误的决定.

推荐阅读
ar_wen2402851455
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有