传递空值时,方法重载解析系统如何决定调用哪个方法? [英] How does the method overload resolution system decide which method to call when a null value is passed?

查看:26
本文介绍了传递空值时,方法重载解析系统如何决定调用哪个方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

例如你有一个类型:

public class EffectOptions
{
    public EffectOptions ( params object [ ] options ) {}

    public EffectOptions ( IEnumerable<object> options ) {}

    public EffectOptions ( string name ) {}

    public EffectOptions ( object owner ) {}

    public EffectOptions ( int count ) {}

    public EffectOptions ( Point point ) {}

}

这里我只给出了使用构造函数的例子,但如果它们是类型本身的非构造函数方法,结果将是相同的,对吗?

Here I just give the example using constructors but the result will be the same if they were non-constructor methods on the type itself, right?

所以当你这样做时:

EffectOptions options = new EffectOptions (null);

会调用哪个构造函数,为什么?

which constructor would be called, and why?

我可以自己测试这个,但我想了解重载解析系统是如何工作的(不确定它是不是这么叫的).

I could test this myself but I want to understand how the overload resolution system works (not sure if that's what it's called).

推荐答案

有关确切规则,请参阅 重载解析规范.但简单地说,它是这样的.

For the exact rules, see the overload resolution spec. But briefly, it goes like this.

首先,列出所有可访问的构造函数.

First, make a list of all the accessible constructors.

public EffectOptions ( params object [ ] options )
public EffectOptions ( IEnumerable<object> options ) 
public EffectOptions ( string name )
public EffectOptions ( object owner ) 
public EffectOptions ( int count ) 
public EffectOptions ( Point point )

接下来,消除所有不适用的构造函数.适用的构造函数是这样一种构造函数,其中每个形式参数都有一个相应的参数,并且该参数可以隐式转换为形式参数类型.假设 Point 是一种值类型,我们消除了int"和Point"版本.那离开

Next, eliminate all the inapplicable constructors. An applicable constructor is one where every formal parameter has a corresponding argument, and the argument is implicitly convertible to the formal parameter type. Assuming that Point is a value type, we eliminate the "int" and "Point" versions. That leaves

public EffectOptions ( params object[] options )
public EffectOptions ( IEnumerable<object> options ) 
public EffectOptions ( string name )
public EffectOptions ( object owner ) 

现在,我们必须考虑带有params"的那个是否适用于expandedunexpanded 形式.在这种情况下,它适用于两种形式.发生这种情况时,我们会丢弃 展开的 表单.这样就离开了

Now, we have to consider whether the one with "params" is applicable in its expanded or unexpanded form. In this case it is applicable in both forms. When that happens, we discard the expanded form. So that leaves

public EffectOptions ( object[] options )
public EffectOptions ( IEnumerable<object> options ) 
public EffectOptions ( string name )
public EffectOptions ( object owner ) 

现在我们必须确定最佳适用的候选人.最佳规则很复杂,但简而言之,越具体越好.长颈鹿比哺乳动物更具体,哺乳动物比动物更具体,动物比物体更具体.

Now we must determine the best of the applicable candidates. The bestness rules are complicated, but the short version is that more specific is better than less specific. Giraffe is more specific than Mammal, Mammal is more specific than Animal, Animal is more specific than object.

object 版本比所有版本都不够具体,因此可以将其删除.IEnumerable 版本没有 object[] 版本那么具体(你明白为什么吗?)所以它也可以被消除.那离开

The object version is less specific than all of them, so it can be eliminated. The IEnumerable<object> version is less specific than the object[] version (do you see why?) so it can be eliminated too. That leaves

public EffectOptions ( object[] options )
public EffectOptions ( string name )

现在我们被困住了.object[] 既不比 string 更具体,也不比 string 更具体.因此,这给出了歧义错误.

And now we are stuck. object[] is neither more nor less specific than string. Therefore this gives an ambiguity error.

那只是一个简短的草图;真正的决胜局算法要复杂得多.但这些都是基础.

That is just a brief sketch; the real tiebreaking algorithm is much more complicated. But those are the basics.

这篇关于传递空值时,方法重载解析系统如何决定调用哪个方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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