为什么方法重载在这个C#程序不工作? [英] Why is method overloading not working in this C# program?

查看:135
本文介绍了为什么方法重载在这个C#程序不工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

namespace test
{
    class Program
    {

        static void Main(string[] args)
        {
            Derived obj = new Derived();
            int i = 10;
            obj.Foo(i);

            Console.ReadLine();
        }

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



该计划的根据输出我应该是美孚(INT),但输出来作为美孚(对象),请帮助我理解输出之探源

output of the program according to me should be Foo(int) but output is coming as Foo(object) please help me in understanding the diffrence in output

推荐答案

好问题,我可以重现你的结果。如果一个人需要看看在C#规格一会发现以下片段:

Good question, I can reproduce your results. If one takes a look at the C# specifications one will find the following snippets:

7.5.3重载

例如,对于一个方法调用的候选集不
方法包括标记为override(§7.4),并在基类
方法不是候选人,如果在派生类中的任何方法适用
(§7.6.5.1)。

For example, the set of candidates for a method invocation does not include methods marked override (§7.4), and methods in a base class are not candidates if any method in a derived class is applicable (§7.6.5.1).

7.4成员查找

否则,该集由所有可访问(3.5节)成员名为N
在T,包括继承的成员和访问的成员名为N $的b $ b在对象。如果T是一个构造类型,成员集合是通过在§10.3.2中描述替换类型实参获得

成员包括override修饰符从集合被排除在外。

Otherwise, the set consists of all accessible (§3.5) members named N in T, including inherited members and the accessible members named N in object. If T is a constructed type, the set of members is obtained by substituting type arguments as described in §10.3.2. Members that include an override modifier are excluded from the set.

7.6 .5.1方法调用

的候选方法集被减少到仅包含从
最派生类型唯一方法:对于该集中,其中C是其中方法F被宣布为
型,每个方法CF在基地
C类中声明的所有方法都是从集合中删除此外,如果C比对象以外的类类型
,在接口类型中声明的所有方法都
从集合中删除。

The set of candidate methods is reduced to contain only methods from the most derived types: For each method C.F in the set, where C is the type in which the method F is declared, all methods declared in a base type of C are removed from the set. Furthermore, if C is a class type other than object, all methods declared in an interface type are removed from the set.

听起来有点复杂?即使是C#的设计师似乎这么认为,并把在'有用的'注意:

Sounds a bit complicated? Even the C# designers seem to think so and put in the 'helpful' note:

7.6.5.1方法调用

上述决议规则的直观效果是
如下:要找到特定的方法的一个方法$调用b $ b调用,开始通过方法调用和
所示的类型的进行了继承链,直到至少一适用,
访问的,非重写的方法声明
发现
的。然后在一套适用,
访问的,非重写对该类型中声明的方法执行
类型推断和重载决策,并调用由此选定的
法。如果没有找到方法,尝试,而不是处理
调用作为扩展方法调用。

The intuitive effect of the resolution rules described above is as follows: To locate the particular method invoked by a method invocation, start with the type indicated by the method invocation and proceed up the inheritance chain until at least one applicable, accessible, non-override method declaration is found. Then perform type inference and overload resolution on the set of applicable, accessible, non-override methods declared in that type and invoke the method thus selected. If no method was found, try instead to process the invocation as an extension method invocation.

如果我们看一看在派生类中,我们看到了两种可能的方法对C#中使用:

If we take a look at your derived class, we see two possible methods for C# to use:

 A) public override void Foo(int i) 
 B) public void Foo(object i)

让我们用这最后的清单!

Let's use that last checklist!

适用性 - A和B都适用 - (都是无效的,都被命名为'富'和双方都能接受的整数值) 。
辅助功能 - A和B都可以访问(公共)
没有覆盖 - 只有B未覆盖

Applicability - Both A and B are applicable -(both are void, both are named 'Foo' and both can accept an integer value). Accessibility - Both A and B are accessible (public) Not Overridden - Only B is not overridden.

别急,你可能会说! A比B更明确!

But wait you might say! A is more specific than B!

正确的,但这种考虑是只发的之后的我们忽略选项A.作为埃里克利珀(设计师之一)所言< A HREF =http://ericlippert.com/2013/12/23/closer-is-better/#more-1806相对=nofollow>更紧密总是比远越好。(感谢安东尼Pegram)

Correct, but that consideration is only made after we've disregarded option A. As Eric Lippert (one of the designers) puts it Closer is always better than farther away. (Thanks Anthony Pegram)

附录

有永远的'新'的关键字

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

    public void Foo(object i)
    {
        Console.WriteLine("Foo(object)");
    }
}



虽然对于另一个问题最左边的细节!

Though the specifics of that best left for another question!

这篇关于为什么方法重载在这个C#程序不工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆