12

我不小心在 C# 中重载了一个构造函数,如下所示:

public MyClass(string myString) 
{
    // Some code goes here 
}

public MyClass(string myString, bool myParameter = false) 
{
   // Some different code here
}

使用此代码,我的项目编译得很好。如果我只用一个string参数调用构造函数,C# 如何决定我要使用哪个构造函数?为什么在语法上允许此功能?

4

5 回答 5

13

来自MSDN:(添加了重点)

如果两个候选者被判断为同样好,则优先考虑没有可选参数的候选者,在调用中省略了这些参数。这是对具有较少参数的候选者的重载解决方案的普遍偏好的结果。

于 2012-07-20T18:40:23.453 回答
11

为什么在语法上允许此功能?

就生成的 IL 而言,第二个构造函数仍然是两个参数。唯一的区别是第二个参数有一个提供默认值的属性。

就编译器而言,当您使用单个字符串调用构造函数时,第一个在技术上仍然更合适。当您使用单个参数调用它时,最佳匹配是第一个构造函数,而第二个不会被调用。

C# 规范说明了这一点。在 7.5 中,它声明“......实例构造函数采用重载决议来确定要调用的候选函数成员集中的哪一个。” 然后在 7.5.3.2 中规定了具体规则,该具体规则适用于:

否则,如果 MP 的所有参数都有对应的参数,而默认参数需要替换 MQ 中的至少一个可选参数,则 MP 优于 MQ。

在这种情况下,MP(您的第一个构造函数)具有所有参数,但 MQ(您的第二个)需要“至少一个可选参数”。

于 2012-07-20T18:37:14.047 回答
2

命名和可选参数的使用通过以下方式影响重载决议:

如果方法、索引器或构造函数的每个参数都是可选的,或者按名称或位置对应于调用语句中的单个参数,并且该参数可以转换为参数的类型,则该方法、索引器或构造函数是执行的候选对象.

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

如果两个候选者被判断为同样好,则优先考虑没有可选参数的候选者,在调用中省略了这些参数。这是对具有较少参数的候选者的重载解决方案的普遍偏好的结果。

引用自MSDN

于 2012-07-20T18:38:00.100 回答
1

带有可选参数的方法将被重载隐藏。

甚至还有一个 ReSharper 规则来警告你。

在此处输入图像描述

在这里你可以找到关于为什么允许它的有用讨论。有些人甚至认为这根本不是问题。

http://youtrack.jetbrains.com/issue/RSRP-287157

于 2012-07-20T18:48:46.147 回答
0

我打赌它会选择第一个更合适的。

命名和可选参数的使用通过以下方式影响重载决议:

  • 如果方法、索引器或构造函数的每个参数都是可选的,或者按名称或位置对应于调用语句中的单个参数,并且该参数可以转换为参数的类型,则该方法、索引器或构造函数是执行的候选对象.

  • 如果找到多个候选者,则将首选转换的重载决策规则应用于
    显式指定的参数。可选参数的省略参数将被
    忽略。

  • 如果两个候选者被判断为同样好,则优先考虑没有可选参数的候选者,
    在调用中省略了这些参数。这是对具有 较少参数
    的候选者的重载解决方案的普遍偏好的结果。

于 2012-07-20T18:35:15.497 回答