C#中的可选参数总是以这种方式工作。对于任何给定的调用,如果有两个适用的重载,并且其中一个需要编译器将默认值用作参数,而另一个则不需要,则不需要使用默认值的"赢得"。以下是一个简单的例子:
using System;
class Test
{
static void Main()
{
Foo();
}
static void Foo() =>
Console.WriteLine("Parameterless");
static void Foo(int x = 0) =>
Console.WriteLine("Parameterized");
}
首先,请记住每个结构体都具有隐式的无参构造函数。来自C# 5 ECMA标准,第16.4.9节:
“与类不同,结构体不允许声明一个无参数实例构造函数。相反,每个结构体都隐式地具有一个无参数实例构造函数,该函数始终返回将所有值类型字段设置为其默认值并将所有引用类型字段设置为 null 的值。”
将这两个事实结合起来,你所看到的行为就很容易理解了。当没有指定任何参数时,将使用无参构造函数而不是带参数的构造函数。在类中也可以完全相同地看到这一点,其中无参构造函数是显式的:
using System;
class Test
{
static void Main()
{
Foo f = new Foo();
}
}
class Foo
{
public Foo()
{
Console.WriteLine("Parameterless");
}
public Foo(int x = 0, int y = 0)
{
Console.WriteLine("Parameterized");
}
}
所以你看到的是C#语言完全一致的行为。可能不是你想要的行为,但我相信这种行为是非常合理的。
请注意,如果您指定了任何参数,例如new Foo(x: 0)
,那么将选择参数化的重载,并且默认值将用于任何没有对应参数的参数。
正如你在其他地方所说的那样,解决这个问题的方法是声明一个具有可选参数的静态方法,它没有无参重载。这样,无论提供哪些参数,都会调用同一个方法 - 然后该方法可以调用构造函数。