C# 4.0 可选 out/ref 参数
C# 4.0 是否允许可选的 out
或 ref
参数?
Does C# 4.0 allow optional out
or ref
arguments?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
C# 4.0 是否允许可选的 out
或 ref
参数?
Does C# 4.0 allow optional out
or ref
arguments?
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(11)
不可以。
解决方法是使用另一个没有 out / ref 参数的方法进行重载,该方法仅调用您当前的方法。
如果您有 C# 7.0,您可以简化:
(感谢@Oskar / @Reiner 指出了这一点。)
No.
A workaround is to overload with another method that doesn't have out / ref parameters, and which just calls your current method.
If you have C# 7.0, you can simplify:
(Thanks @Oskar / @Reiner for pointing this out.)
正如已经提到的,这是根本不允许的,但我认为这是非常有道理的。
但是,要添加更多详细信息,请引用 C# 4.0 规范,第 21.1 节:
As already mentioned, this is simply not allowed and I think it makes a very good sense.
However, to add some more details, here is a quote from the C# 4.0 Specification, section 21.1:
不,但另一个很好的选择是让该方法使用通用模板类作为可选参数,如下所示:
然后您可以按如下方式使用它:
No, but another great alternative is having the method use a generic template class for optional parameters as follows:
Then you can use it as follows:
实际上有一种 C# 允许的方法可以做到这一点。这又回到了 C++,并且违反了 C# 良好的面向对象结构。
请谨慎使用此方法!
以下是使用可选参数声明和编写函数的方法:
然后像这样调用函数:
为了编译该函数,您需要在项目选项中启用不安全代码。这是一个非常老套的解决方案,通常不应该使用,但如果您出于某种奇怪的、神秘的、神秘的、受管理启发的决定,确实需要 C# 中的可选输出参数,那么这将允许您做到这一点。
There actually is a way to do this that is allowed by C#. This gets back to C++, and rather violates the nice Object-Oriented structure of C#.
USE THIS METHOD WITH CAUTION!
Here's the way you declare and write your function with an optional parameter:
Then call the function like this:
In order to get this to compile, you will need to enable unsafe code in the project options. This is a really hacky solution that usually shouldn't be used, but if you for some strange, arcane, mysterious, management-inspired decision, REALLY need an optional out parameter in C#, then this will allow you to do just that.
ICYMI:包含在 C# 7.0 枚举的新功能中 此处,现在允许“discards”作为 _ 形式的 out 参数,让您忽略不关心的 out 参数:
p.GetCooperatives(out var x , 出去 _); // 我只关心 x
PS 如果您也对“out var x”部分感到困惑,请阅读链接上有关“Out Variables”的新功能。
ICYMI: Included on the new features for C# 7.0 enumerated here, "discards" is now allowed as out parameters in the form of a _, to let you ignore out parameters you don’t care about:
p.GetCoordinates(out var x, out _); // I only care about x
P.S. if you're also confused with the part "out var x", read the new feature about "Out Variables" on the link as well.
不可以,但您可以使用委托(例如
Action
)作为替代方案。当我遇到我认为需要可选输出参数的情况时,部分受到 Robin R 回答的启发,我改为使用
Action
委托。我借用了他的示例代码来修改Action
的使用,以显示差异和相似之处:这样做的优点是可选变量在源代码中显示为普通 int (编译器将其包装在闭包类中,而不是我们将其显式包装在用户定义的类中)。
该变量需要显式初始化,因为编译器无法假定在函数调用退出之前将调用
Action
。它并不适合所有用例,但对于我的实际用例(一个为单元测试提供数据的函数,以及新的单元测试需要访问返回值中不存在的某些内部状态的函数)效果很好。
No, but you can use a delegate (e.g.
Action
) as an alternative.Inspired in part by Robin R's answer when facing a situation where I thought I wanted an optional out parameter, I instead used an
Action
delegate. I've borrowed his example code to modify for use ofAction<int>
in order to show the differences and similarities:This has the advantage that the optional variable appears in the source as a normal int (the compiler wraps it in a closure class, rather than us wrapping it explicitly in a user-defined class).
The variable needs explicit initialisation because the compiler cannot assume that the
Action
will be called before the function call exits.It's not suitable for all use cases, but worked well for my real use case (a function that provides data for a unit test, and where a new unit test needed access to some internal state not present in the return value).
对于 C# 6.0 及更低版本,使用不带 out 参数的重载方法来调用带 out 参数的方法。当特别询问 C# 4.0 是否可以有可选的 out 参数时,我不确定为什么 C# 7.0 for .NET Core 甚至是该线程的正确答案。答案是否定的!
Use an overloaded method without the out parameter to call the one with the out parameter for C# 6.0 and lower. I'm not sure why a C# 7.0 for .NET Core is even the correct answer for this thread when it was specifically asked if C# 4.0 can have an optional out parameter. The answer is NO!
对于简单类型,您可以使用不安全代码来执行此操作,尽管这不是惯用的也不推荐。就像这样:
也就是说,没有理论上的原因 C# 最终不能允许使用安全代码执行类似上面的操作,如下所示:
不过事情可能会变得有趣:
For simple types you can do this using unsafe code, though it's not idiomatic nor recommended. Like so:
That said, there's no theoretical reason C# couldn't eventually allow something like the above with safe code, such as this below:
Things could get interesting though:
直接的问题已经在其他好评如潮的答案中得到了回答,但有时根据您想要实现的目标考虑其他方法是值得的。
如果您想要一个可选参数来允许调用者可能从您的方法中请求额外的数据作为某些决策的基础,则另一种设计是将该决策逻辑移至您的方法中,并允许调用者有选择地传递该值例如,这里有一个确定向量的罗盘点的方法,在该方法中我们可能希望传回向量的大小,以便调用者可以决定是否应该在罗盘之前达到某个最小阈值点判断距离原点足够远,因此明确有效:
在这种情况下,我们可以将“最小幅度”逻辑移至方法中,最终得到一个更清晰的实现,特别是因为计算幅度涉及平方根如果我们只想比较大小,那么计算效率很低,因为我们可以使用平方值来完成:
当然,这可能并不总是可行。由于其他答案提到了 C# 7.0,如果您真正做的是返回两个值并允许调用者选择忽略一个值,那么惯用的 C# 将返回两个值的元组,并使用 C# 7.0 的元组和位置初始化器和 _“discard”参数:
The direct question has been answered in other well-upvoted answers, but sometimes it pays to consider other approaches based on what you're trying to achieve.
If you're wanting an optional parameter to allow the caller to possibly request extra data from your method on which to base some decision, an alternative design is to move that decision logic into your method and allow the caller to optionally pass a value for that decision criteria in. For example, here is a method which determines the compass point of a vector, in which we might want to pass back the magnitude of the vector so that the caller can potentially decide if some minimum threshold should be reached before the compass-point judgement is far enough away from the origin and therefore unequivocally valid:
In this case we could move that "minimum magnitude" logic into the method and end-up with a much cleaner implementation, especially because calculating the magnitude involves a square-root so is computationally inefficient if all we want to do is a comparison of magnitudes, since we can do that with squared values:
Of course, that might not always be viable. Since other answers mention C# 7.0, if instead what you're really doing is returning two values and allowing the caller to optionally ignore one, idiomatic C# would be to return a tuple of the two values, and use C# 7.0's Tuples with positional initializers and the _ "discard" parameter:
像这样又怎样呢?
您仍然需要从 C# 向参数传递一个值,但它是一个可选的引用参数。
What about like this?
You still have to pass a value to the parameter from C# but it is an optional ref param.