您的位置:首页 > 编程语言 > C#

[c#美味] c#4中默认参数和命名参数后的函数重载

2010-05-30 19:06 267 查看

问题提出

由于C#4中新增了默认参数和命名参数,导致函数重载的情况变得比以前复杂了一些。

举例如下,假设有下面4个函数:

static void Fun(string name, int num = 1)
{
}

static void Fun(object o)
{
}

static void Fun(int num, string name = "Greenerycn")
{
}

static void Fun(int num)
{
}

调用的代码如下:

static void Main(string[] args)
{
Fun(99);
}




那么这会调用哪个函数呢?

 

重载决策规则

什么是重载决策呢?根据MSDN提供的资料:


重载决策是一种编译时机制,用于在给定了参数列表和一组候选函数成员的情况下,选择一个最佳函数成员来实施调用。

使用命名实参和可选实参将在以下方面对重载决策产生影响:

如果方法、索引器或构造函数的各个形参均为可选,或者按名称或位置与调用语句中的单个实参对应,并且该实参可转换为形参的类型,则该方法、索引器或构造函数是执行的候选项。

如果找到多个候选项,则会将首选转换的重载决策规则应用于显式指定的实参。将忽略可选形参已省略的实参。

如果两个候选项不相上下,则会将没有可选形参的候选项作为首选项,对于这些可选形参,已在调用中为其省略了实参。这是具有较少形参的候选项的重载决策中一般首选项的结果。

英文的如下:

A method, indexer, or constructor is a candidate for execution if each of its parameters either is optional or corresponds, by name or by position, to a single argument in the calling statement, and that argument can be converted to the type of the parameter.

If more than one candidate is found, overload resolution rules for preferred conversions are applied to the arguments that are explicitly specified. Omitted arguments for optional parameters are ignored.

If two candidates are judged to be equally good, preference goes to a candidate that does not have optional parameters for which arguments were omitted in the call. This is a consequence of a general preference in overload resolution for candidates that have fewer parameters.



上面这段规则太拗口了。。。不管是英文的还是中文的都不好理解。还是按上面的例子来说明吧。

 

实例分析

 

调用函数:Fun(99)

实参:99, 类型int

实参个数:1

 

Fun的重载函数总共有4个,我们一一分析:

Fun(string name, int num = 1)

根据规则1,它的第一个参数name类型是string和99即int类型不匹配,而且name也不是有默认值可省略的参数,所以它不能列为候选。

 

Fun(object o)

根据规则1,因为int类型是可以转换为object类型的,而且参数个数也相同,列为候选。

 

Fun(int num, string name = "Greenerycn")

根据规则1,因为num是int类型,99也是int类型,而且name是有默认值可省略的参数,所以也列为候选。

 

Fun(int num)

根据规则1,因为num是int类型,99也是int类型,两个类型相同,也没有其他的行参,故列为候选。

 

这样看来,我们就有3个候选了,即:

Fun(object o)

Fun(int num, string name = "Greenerycn")

Fun(int num)

 

现在要处理多个候选的情况,按照重载的一般规则(http://msdn.microsoft.com/zh-cn/vstudio/aa691338(VS.71).aspx),即转换好的优先。那么

Fun(object o)

就被淘汰出局,因为99是int类型,int转换为int显然比转换为object好。

 

ok,现在还有两个:

Fun(int num, string name = "Greenerycn")

Fun(int num)

 

根据规则3,优先选择没有可选形参的函数。最终得出匹配的函数是:

Fun(int num)

 

即:Fun(99) 实际上调用的是Fun(int num)  这个函数。

 

我现在还没找到规则2的例子,等找到后再完善这篇文章吧。

 

参考资料:

Named and Optional Arguments (C# Programming Guide)

http://msdn.microsoft.com/en-us/library/dd264739.aspx

命名实参和可选实参(C# 编程指南)

http://msdn.microsoft.com/zh-cn/library/dd264739.aspx

New features in CSharp 4.0.doc

http://code.msdn.microsoft.com/cs2010samples/Release/ProjectReleases.aspx?ReleaseId=4175

C# 语言规范:7.4.2 重载决策

http://msdn.microsoft.com/zh-cn/vstudio/aa691336(VS.71).aspx

使用索引器(c#编程指南)

http://msdn.microsoft.com/zh-cn/library/2549tw02.aspx

Named arguments and overload resolution:

http://blogs.msdn.com/b/samng/archive/2009/04/01/named-arguments-and-overload-resolution.aspx
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: