使用默认参数重载的构造函数

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

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

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

为什么语法允许这个function?

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

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

C#规范解释了这一点。 在7.5中,它声明“……实例构造函数使用重载决策来确定要调用的候选函数成员集中的哪一个。” 然后在7.5.3.2中指定特定规则,其中适用此特定规则:

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

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

来自MSDN :(重点补充)

如果判断两个候选者同样好,则优先选择没有可选参数的候选者,该参数在调用中被省略。 这是对具有较少参数的候选者的重载分辨率的一般偏好的结果

使用命名和可选参数会以下列方式影响重载解析:

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

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

如果判断两个候选者同样好,则优先选择没有可选参数的候选者,该参数在调用中被省略。 这是对具有较少参数的候选者的重载分辨率的一般偏好的结果。

引用自MSDN 。

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

甚至有一个ReSharper规则可以警告你。

在此处输入图像描述

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

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

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

使用命名和可选参数会以下列方式影响重载解析:

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

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

  • 如果两个候选人被判断为同样好,则优先选择没有可选参数的候选人
    调用中省略了参数。 这是一个结果
    对具有的候选人的重载决议的一般偏好
    参数更少。