我意外地在C#中重载了一个构造函数,如下所示:
public MyClass(string myString)
{
// Some code goes here
}
public MyClass(string myString, bool myParameter = false)
{
// Some different code here
}
使用此代码,我的项目编译得很好。如果我只用string
参数调用构造函数,C#如何决定我想使用哪个构造函数?为什么在语法上允许这个功能?
答案 0 :(得分:13)
来自MSDN :(强调添加)
如果两个候选人被判断为同样好,则优先选择没有可选参数的候选人,其中参数在调用中被省略。这是对具有较少参数的候选人的重载分辨率的一般偏好的结果。
答案 1 :(得分:10)
为什么语法允许这个功能?
就生成的IL而言,第二个构造函数仍然是两个参数。唯一的区别是第二个参数有一个提供默认值的属性。
就编译器而言,当您使用单个字符串调用构造函数时,第一个在技术上仍然更合适。当你用一个参数调用它时,最好的匹配是第一个构造函数,第二个不会被调用。
C#规范解释了这一点。在7.5中,它声明“......实例构造函数使用重载决策来确定要调用哪个候选函数成员集。”然后在7.5.3.2中指定特定规则,其中适用此特定规则:
否则,如果MP的所有参数都有相应的参数,而默认参数需要替换MQ中的至少一个可选参数,那么MP优于MQ。
在这种情况下,MP(您的第一个构造函数)具有所有参数,但MQ(您的第二个)需要“至少一个可选参数。”
答案 2 :(得分:2)
使用命名参数和可选参数会影响重载的解决方案 以下方式:
方法,索引器或构造函数是执行的候选者 它的参数是可选的,也可以是名称或对应的 位置,调用语句中的单个参数,以及 参数可以转换为参数的类型。
如果找到多个候选者,则重载解析规则为 首选转换应用于显式的参数 指定。忽略可选参数的省略参数。
如果两名候选人被判断为同样好,则优先选择a 候选者没有可选参数的参数 在通话中被省略了。这是一般的结果 对于拥有较少的候选人,重载决议的偏好 参数。
引自MSDN。
答案 3 :(得分:1)
带有可选参数的方法将被重载隐藏。
甚至有一个ReSharper规则可以警告你。
在这里,您可以找到有关为何允许的有用讨论。 有些人甚至认为这根本不是问题。
答案 4 :(得分:0)
我打赌它会选择第一个更合适。
使用命名和可选参数会以下列方式影响重载解析:
方法,索引器或构造函数是执行的候选者 它的每个参数都是可选的或对应的,名称或 按位置,调用语句中的单个参数,以及 参数可以转换为参数的类型。
如果找到多个候选项,则重载决策规则为
首选转换应用于作为
的参数
明确指定。可选参数的省略参数为
忽略。
如果两名候选人被认为同样优秀,则优先选择a 候选人没有可选参数 调用中省略了参数。这是一个结果 对于有候选人的候选人,一般优先考虑重载决议 参数较少。