【发布时间】:2015-09-06 11:39:04
【问题描述】:
我发现 C# 中的“命名参数”这一特性非常奇怪,因为我从中发现了两个缺陷。书中说“命名参数使您能够“以任何顺序传递参数”。
我认为这个 C# 功能存在两个缺陷:
它违反了计算机科学中的“信息隐藏”。 (即:使用该方法的最终用户需要知道参数名称和数据类型才能使用该功能。)来自 Java 背景,这很奇怪。为什么要将参数名称暴露给用户末尾?
它容易产生歧义,从而导致错误。 (程序员需要做额外的思考,当程序员最终编写使用相同方法名称的方法(也称为重载方法)时,问题可能会蔓延。当您有两个具有相同名称的方法时,您总是会得到“调用不明确即使另一个方法具有不同数据类型的额外参数,彼此也具有相同的参数。我能想到的唯一解决方法是使数据类型成为“强制参数”,也就是没有默认值的参数,所以编译器会这样做不要混淆。但是这个修复只是一个绷带解决方案,会导致另一个最坏的情况(见下文)
这个行业的人至今还在使用这个概念吗?如果是这样,为什么要打破这两个规则以赋予“在调用方法时以任意顺序传递参数的能力”?
TLDR:一个示例,通过介绍可能的最坏情况(编译器选择了错误的方法调用......尽管这两种方法相似),从而使我所谈论的内容更加清晰:
namespace ConsoleApplication1
{
class Venusaur
{
static void Main(string[] args)
{
new Venusaur().optMethod(fourth: "s");
}
public void optMethod( string third , string fourth = "hello", int fifth = 23, string two = "w")
{
// what if I wanted this method to run instead of the method below me
Console.WriteLine("did not execute");
}
public void optMethod(string third = "Byte", string fourth = "hello", int fifth = 4)
{
// But this method ran instead
Console.WriteLine("run");
}
}
}
【问题讨论】:
-
如果你想运行
optMethod的第一个声明,你需要明确指定third变量:new Venusaur().optMethod("thirdStr", fourth: "s"); -
我不确定这个问题是否会被考虑。但是,要回答您的问题:使用命名参数是非常不寻常的,即使它在 C# 中是允许的。我能回忆起的唯一真实世界的例子是 XNA 和 MonoGame(老实说,它看起来很丑很奇怪,我认为他们本可以做得更好)。
-
@jsve 显式指定第三个变量将不起作用,因为这两种方法的参数名称相同,因此编译器会感到困惑。它会产生“歧义方法调用错误”。我已经尝试过这段代码: new Venusaur().optMethod(third: "thirdStr", Fourth: "s");不太清楚你是如何“突出显示你的代码”来响应和回复的。
-
@Nicholas 我明白你的意思了。 C# 的方法解析很复杂,但它被很好地指定并且命名参数也不会改变这些规则:stackoverflow.com/questions/5173339/…
标签: c# methods parameters arguments optional-parameters