考虑以下定义:
class Foo
{
string Asd;
List<int> Qwert;
public Foo(string Bar, List<int> Baz = null)
{
// Set up instance from parameters
this.Asd = Bar;
this.Qwert = Baz ?? new List<int>;
}
public Foo(string Qwop)
{
// Code which sets up the instance based on what Qwop is
// E.g.: take Asd and Qwert values from a previous storage
}
}
现在,如果我将构造函数调用为Foo foo = new Foo("value");
,则执行第二个构造函数。
如何让编译器强制使用命名参数进行调用?因为两个建设者都是&#39;第一个参数是string
,有明显的模糊性。 (无论如何,我无法逃避或解决这个问题,我们需要采用string
。)
Foo foo = new Foo("value"); // NOT fine
Foo foo = new Foo(Bar: "value"); // Fine, first constructor
Foo foo = new Foo("value", new List<int> { 0, 1, 2 }; // Fine, as it is clearly 1st
Foo foo = new Foo(Qwop: "anothervalue"); // Fine, second constructor
我考虑过声明一个额外的构造函数:
[Obsolete("Parameterization would be ambiguos. Please specify what string is by using named parameters", true)]
public Foo(string param)
{
throw new ArgumentException();
}
我认为这意味着如果没有命名参数,代码会调用此代码并且编译将失败。但是之前的构建失败了,因为
显然,这是不行的。但我的另一个尝试:键入&#39; Program.Foo&#39;已经定义了一个名为&#39; Foo&#39;使用相同的参数类型
class Foo
{
public Foo(IFooInvoker invoker)
{
if (invoker is FooInvokerBarBaz) { ... }
else if (invoker is FooInvokerQwop) { ... }
}
}
interface IFooInvoker { ... }
class FooInvokerBarBaz : IFooInvoker { ... }
class FooInvokerQwop : IFooInvoker { ... }
// And calling the whole from Main by
Foo foo = new Foo(new FooInvokerBarBaz("bar", new List<int> { 0, 1, 2 });
// or
Foo foo = new Foo(new FooInvokerQwop("qwop");
看起来方式过于复杂,丑陋而且我认为违反了多项设计原则。
答案 0 :(得分:5)
基本上,你不能。它只是语言的一部分。如何让编译器强制使用命名参数进行调用?
可以做的是使构造函数变为私有,而是公开静态工厂方法,这些方法解释了它们构造实例的内容。
public static Foo FromBarAndBaz(string bar, List<int> baz = null)
{
return new Foo(bar, baz);
}
public static Foo FromQwop(string qwop)
{
return new Foo(qwop);
}
(为简单起见,您可能也希望在构造函数中强制baz
。)
请注意,我已更改参数名称以符合正常的.NET命名约定。
答案 1 :(得分:1)
public Foo(string bar, List<int> baz) // baz is now required, but can be null
public Foo(string qwop)
或者您可以将构造函数设为私有并公开静态方法:
private Foo(string bar, List<int> baz)
private Foo(string qwop)
public static Foo FromBarBaz(string bar, List<int> baz = null)
public static Foo FromQwop(string qwop)
(作为次要注释,参数should be camelCased,而不是PascalCased)