I have a method that has several overrides. In one of the more expanded overrides, I want to return an OUT parameter but not in my simpler overrides. For example:
我有一个方法,它有几个重写。在一个扩展较多的重写中,我想返回一个out参数,但不是在我的较简单重写中。例如:
public bool IsPossible(string param1, int param2)
public bool IsPossible(string param1, int param2, out bool param3)
The way I am currently achieving this, is like so:
我目前实现这一点的方式是这样的:
public bool IsPossible(string param1, int param2) {
bool temp;
return IsPossible(param1, param2, out temp);
}
Is there a better way to achieve this? Can I (or should I) use a null-able out parameter?
有没有更好的方法来实现这一点?我可以(或应该)使用一个可以为空的输出参数吗?
更多回答
That looks fine to me. A out
cannot be optional for technical reasons (it needs to point to a valid instance).
在我看来没问题。出于技术原因,out不能是可选的(它需要指向有效的实例)。
Since C# 7.0 you can pass a Discard (_
) into the method:
从C# 7.0开始,你可以将一个Discard(_)传入方法:
return IsPossible(param1, param2, out _);
See: https://learn.microsoft.com/en-us/dotnet/csharp/discards
请参阅:https://learn.microsoft.com/en-us/dotnet/csharp/discards
OP:
点评:
Can I (or should I) use a null-able out parameter?
A nullable out parameter won't do you much good. This:
可为空的out参数不会对您有多大好处。这一点:
public bool IsPossible( string param1, int param2, out bool? param3 )
{
...
}
doesn't make param3
optional. It changes the semantics of what param3
is. A bool?
(aka Nullable<bool>
) widens the domain of param3
from 2 values ( true
and false
) to 3, adding a third value (null
), usually interpreted as missing/unknown. The caller still must supply all three arguments.
不会使参数3成为可选的。它改变了param3是什么的语义。一个bool?(也称为Nullable
)将参数3的范围从2个值(TRUE和FALSE)扩大到3,添加第三个值(NULL),通常被解释为缺失/未知。调用方仍然必须提供所有三个参数。
Overloading IsPossible()
by providing an overload -- the "don't care" scenario -- that discards the reference parameter is the proper solution.
重载是可能的(),方法是提供一个重载--“无关”场景--丢弃引用参数是正确的解决方案。
A 'ref' or 'out' parameter cannot have a default value.
The way you've done it is just fine. Sorry, no silver bullet.
你做这件事的方式很好。抱歉,没有灵丹妙药。
Personally I think it is fine "as is". Another approach, though, is to return a composite return value (perhaps an immutable struct with 2 properties); that avoids the fact that some people avoid out
. I am not one of those people :p
就我个人而言,我认为“原样”很好。然而,另一种方法是返回复合返回值(可能是具有两个属性的不可变结构);这避免了一些人避免OUT的事实。我不是那种人:P
Re the question; indeed, out/ref can't be optional.
这是个问题;实际上,out/ref不能是可选的。
If you wanted to get unnecessarily fancy you could give the conposite return-type a conversion to bool to allow implicit if
tests.
如果想要不必要的花哨,可以给复合的返回类型一个到bool的转换,以允许隐式的if测试。
Yes, Nullable variables are great. You would then do something like this.
是的,可为空的变量很棒。然后你会做这样的事情。
public bool? IsPossible(string param1, int param2);
var ans = IsPossible("Parm1", 1);
if (ans.HasValue)
{
//working.
}
Very old question. Anyway, there is another possibility.
I do like @aaroncatlin 's answer about discarded variables.
很老的问题。无论如何,还有另一种可能性。我确实喜欢@aaroncatlin‘S关于丢弃变量的回答。
But suppose the 3rd parameter is a byte[] and the caller optionally wants to return a huge number of bytes... Usually this construct is used by native API's.
但是假设第三个参数是byte[],并且调用者可以选择返回大量字节……通常,此构造由本机API使用。
So, if the callee expects the possibility of getting a null reference, we can pass a null as 3rd parameter from an unsafe block like this:
因此,如果被调用者期望获得空引用的可能性,我们可以从不安全块中传递一个空参数作为第三个参数,如下所示:
public unsafe bool IsPossible(string param1, int param2) {
return IsPossible(param1, param2, out *(bool*)null);
}
In this case useless. But in case of optional byte[] it does make sense.
在这种情况下没用。但在可选byte[]的情况下,它确实有意义。
更多回答
Having a hard time believing the reason for not supporting this is technical more than marketing priorities. Seems the compiler could just create a temp location just as your example--and also for Refs by init'ing with Default(T). Notably, "out/ref (inout)" arguments are supported in SQL Server.
我很难相信不支持这一点的原因更多的是技术上的,而不是营销上的优先考虑。似乎编译器可以像您的示例一样创建一个temp位置--也可以通过使用DEFAULT(T)来初始化引用。值得注意的是,SQL Server支持“out/ref(Inout)”参数。
It's worth to mention, that in C# 7.0 you can use Discards with Underscore sign. Read more here: stackoverflow.com/a/42924200/1319086
值得一提的是,在C#7.0中,您可以使用带有下划线符号的丢弃。点击此处阅读更多内容:Stackoverflow.com/a/42924200/1319086
VB.net does it. C# should automatically allow out/ref to be optional, and fill in a dummy variable when needed in the background.
VB.net做到了。C#应该自动允许out/ref是可选的,并在需要时在后台填充一个伪变量。
Good answer, but you forgot to write out return IsPossible(param1, param2, out _);
答得好,但是你忘了写出返回是可能的(参数1,参数2,输出_);
Thanks. Amended my answer
谢谢。修改了我的答案
I don't find this API style hugely obvious to the caller, personally. Subjective, though.
我个人并不觉得这种API风格对调用者来说非常明显。不过,这是主观的。
What do you mean obvoius to the caller?
你对呼叫者来说,obvoius是什么意思?
well, for starters - there were previously 4 possible outcomes; there are now 3; what are they equivalent of, etc? what does it mean for IsPossible to be null? vs non-null but false? presumable true means "yes it is possible", but the other two are less clear-cut to me.
首先,之前有4种可能的结果;现在有3种;它们相当于什么,等等?对于可能为空的是什么意思?Vs非空但为假?“假定为真”的意思是“是的,这是可能的”,但对我来说,其他两个就不那么明确了。
我是一名优秀的程序员,十分优秀!