为什么C#允许通过可选参数进行模棱两可的函数调用? [英] Why does C# allow ambiguous function calls through optional arguments?

查看:100
本文介绍了为什么C#允许通过可选参数进行模棱两可的函数调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我今天碰到了这一点,但令我惊讶的是,我之前从未注意到这一点.给出一个类似于以下内容的简单C#程序:

I came across this today, and I am surprised that I haven't noticed it before. Given a simple C# program similar to the following:

public class Program
{
    public static void Main(string[] args)
    {
        Method(); // Called the method with no arguments.
        Method("a string"); // Called the method with a string.

        Console.ReadLine();
    }

    public static void Method()
    {
        Console.WriteLine("Called the method with no arguments.");
    }

    public static void Method(string aString = "a string")
    {
        Console.WriteLine("Called the method with a string.");
    }
}

您将获得每个方法调用的注释中显示的输出.

You get the output shown in the comments for each method call.

我理解为什么编译器会选择它所做的重载,但是为什么首先允许这样做呢?我不是在问什么是重载解析规则,我理解这些规则,但是我在问是否有技术上的原因,为什么编译器允许具有相同签名的本质上是两个重载?

I understand why the compiler chooses the overloads that it does, but why is this allowed in the first place? I am not asking what the overload resolution rules are, I understand those, but I am asking if there is a technical reason why the compiler allows what are essentially two overloads with the same signature?

据我所知,具有签名的函数重载与另一个重载的区别仅在于通过拥有一个附加的可选参数,所提供的功能仅是简单地需要该参数(以及所有先前的参数)的情况.

As far as I can tell, a function overload with a signature that differs from another overload only through having an additional optional argument offers nothing more than it would if the argument (and all preceding arguments) were simply required.

它所做的一件事是使程序员(可能没有引起足够重视)认为他们正在调用与实际不同的重载.

One thing it does do is makes it possible for a programmer (who probably isn't paying enough attention) to think they're calling a different overload to the one that they actually are.

我认为这是一个相当不常见的情况,为什么允许这样做的答案可能仅仅是因为不值得禁止它的复杂性,但是还有另一个原因为什么C#只允许通过让函数重载与其他函数有所区别一个额外的可选参数?

I suppose it's a fairly uncommon case, and the answer for why this is allowed may just be because it's simply not worth the complexity to disallow it, but is there another reason why C# allows function overloads to differ from others solely through having one additional optional argument?

推荐答案

埃里克·利珀特(Eric Lippert)可能有答案的观点将我带到了这个 https://meta.stackoverflow.com/a/323382/1880663 ,听起来我的问题只会惹恼他.我将尝试重新措辞,以使其更清楚地表明我在询问语言设计,而且我也没有在寻找规范参考

His point that Eric Lippert could have an answer lead me to this https://meta.stackoverflow.com/a/323382/1880663, which makes it sounds like my question will only annoy him. I'll try to rephrase it to make it clearer that I'm asking about the language design, and that I'm not looking for a spec reference

我很感激!我很高兴谈论语言设计;当发问者不清楚什么可以真正满足他们的要求时,我很烦我.我认为您的问题表达清楚.

I appreciate it! I am happy to talk about language design; what annoys me is when I waste time doing so when the questioner is very unclear about what would actually satisfy their request. I think your question was phrased clearly.

由汉斯(Hans)发表的关于您问题的评论是正确的.语言设计团队非常了解您提出的问题,这与由可选参数/命名参数创建的唯一潜在歧义相去甚远.我们考虑了很长时间的许多情况,并尽可能仔细地设计了该功能,以减轻潜在的问题.

The comment to your question posted by Hans is correct. The language design team was well aware of the issue you raise, and this is far from the only potential ambiguity created by optional / named arguments. We considered a great many scenarios for a long time and designed the feature as carefully as possible to mitigate potential problems.

所有设计过程都是相互竞争的设计原则之间折衷的结果.显然,对于功能的许多争论必须与大量的设计,实施和测试成本,以及由于诸如此类的歧义的意外构造而给用户带来的混乱,错误等形式的成本进行权衡.你指出一个.

All design processes are the result of compromise between competing design principles. Obviously there were many arguments for the feature that had to be balanced against the significant design, implementation and testing costs, as well as the costs to users in the form of confusion, bugs, and so on, from accidental construction of ambiguities such as the one you point out.

我不会重复数十个小时的辩论;让我给您一些要点.

I'm not going to rehash what was dozens of hours of debate; let me just give you the high points.

正如汉斯指出的那样,此功能的主要动机是受欢迎的需求,特别是来自将C#与Office一起使用的开发人员. (并且完全公开了,作为加入C#团队之前为Word和Excel编写C#编程模型的团队中的一个人,我实际上是第一个要求它的人;具有讽刺意味的是,我后来不得不实现几年后,这个困难的功能并没有让我迷失.)Office对象模型设计用于Visual Basic,该语言长期以来一直具有可选的/命名参数支持.

The primary motivating scenario for the feature was, as Hans notes, popular demand, particularly coming from developers who use C# with Office. (And full disclosure, as a guy on the team that wrote the C# programming model for Word and Excel before I joined the C# team, I was literally the first one asking for it; the irony that I then had to implement this difficult feature a couple years later was not lost on me.) Office object models were designed to be used from Visual Basic, a language that has long had optional / named parameter support.

C#4似乎有点瘦".这是因为该版本中完成的许多工作都是基础架构,用于允许与为动态语言设计的对象模型实现更无缝的互操作性.动态类型化功能是显而易见的功能,但是添加了许多其他小的功能,这些功能组合在一起使使用动态和旧式COM对象模型更加容易.命名/可选参数只是其中之一.

C# 4 might have seemed like a bit of a "thin" release in terms of obvious features. That's because a lot of the work done in that release was infrastructure for allowing more seamless interoperability with object models that were designed for dynamic languages. The dynamic typing feature is the obvious one, but there were numerous other small features added that combine together to make working with dynamic and legacy COM object models easier. Named / optional arguments was just one of them.

我们拥有像VB这样的已有语言已有数十年了,并且世界还没有终结的事实,这进一步证明了该功能既可行又有价值.有一个很好的例子,您可以在设计功能的新版本之前从其成功和失败中学习.

The fact that we had existing languages like VB that had this specific feature for decades and the world hadn't ended yet was further evidence that the feature was both doable and valuable. It's great having an example where you can learn from its successes and failures before designing a new version of the feature.

关于您提到的具体情况:我们考虑过进行诸如检测何时可能存在歧义并发出警告的操作,但这随后又打开了另一罐蠕虫.警告必须针对常见,合理且几乎肯定是错误的代码,并且应该有一种明确的方法来解决导致警告消失的问题.编写歧义检测器需要大量工作.相信我,用重载解决方案编写歧义检测花费的时间要比编写处理成功案例的代码花费的时间更长.我们不想花很多时间在难以发现的罕见情况下添加警告,并且可能没有明确的建议来消除警告.

As for the specific situation you mention: we considered doing things like detecting when there was a possible ambiguity and making a warning, but that then opens up a whole other cans of worms. Warnings have to be for code that is common, plausible and almost certainly wrong, and there should be a clear way to address the problem that causes the warning to go away. Writing an ambiguity detector is a lot of work; believe me, it took way longer to write the ambiguity detection in overload resolution than it took to write the code to handle successful cases. We didn't want to spend a lot of time on adding a warning for a rare scenario that is hard to detect and that there might be no clear advice on how to eliminate the warning.

坦率地说,如果您在编写代码时使用了两个名为同一事物的方法,这些方法根据所调用的方法执行的操作完全不同,那么您手上的设计问题就更大了!首先解决该问题,而不用担心有人会意外地调用错误的方法.使其成为正确的调用方法.

Also, frankly, if you write code where you have two methods named the same thing that do something completely different depending on which one you call, you already have a larger design problem on your hands! Fix that problem first, rather than worrying that someone is going to accidentally call the wrong method; make it so that either method is the right one to call.

这篇关于为什么C#允许通过可选参数进行模棱两可的函数调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆