C# 如何显式丢弃 out 参数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/462167/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to explicitly discard an out argument?
提问by Andrew Ducker
I'm making a call:
我打电话:
myResult = MakeMyCall(inputParams, out messages);
but I don't actually care about the messages. If it was an input parameter I didn't care about I'd just pass in a null. If it was the return I didn't care about I'd just leave it off.
但我实际上并不关心这些消息。如果它是一个我不关心的输入参数,我只会传入一个空值。如果这是我不在乎的回报,我就会放弃它。
Is there a way to do something similar with an out, or do I need to declare a variable that I will then ignore?
有没有办法用 out 做类似的事情,还是我需要声明一个我会忽略的变量?
采纳答案by Nolonar
Starting with C# 7.0, it is possible to avoid predeclaring out parameters as well as ignoring them.
从 C# 7.0 开始,可以避免预先声明参数以及忽略它们。
public void PrintCoordinates(Point p)
{
p.GetCoordinates(out int x, out int y);
WriteLine($"({x}, {y})");
}
public void PrintXCoordinate(Point p)
{
p.GetCoordinates(out int x, out _); // I only care about x
WriteLine($"{x}");
}
Source: https://blogs.msdn.microsoft.com/dotnet/2017/03/09/new-features-in-c-7-0/
来源:https: //blogs.msdn.microsoft.com/dotnet/2017/03/09/new-features-in-c-7-0/
回答by Andrew Hare
Unfortunately you are required to pass something because the method is required to set it. So you cannot send null
because the method, being required to set it, would blow up.
不幸的是,您需要传递一些东西,因为需要该方法来设置它。所以你不能发送,null
因为需要设置它的方法会爆炸。
One approach to hide the ugliness would be to wrap the method in another method that does the out
parameter for you like so:
隐藏丑陋的一种方法是将方法包装在另一种方法中,该方法out
为您执行参数,如下所示:
String Other_MakeMyCall(String inputParams)
{
String messages;
return MakeMyCall(inputParams, out messages);
}
Then you can call Other_MakeMyCall
without having to fiddle with out
parameters you don't need.
然后你可以调用Other_MakeMyCall
而不必摆弄out
你不需要的参数。
回答by S?ren Kuklau
If the class of messages
implements IDisposable
, you shouldn't ignore it. Consider something like the following approach (may not be syntactically correct since I haven't written C# in a while):
如果是messages
implements类IDisposable
,则不应忽略它。考虑类似以下方法(可能在语法上不正确,因为我有一段时间没有编写 C#):
using (FooClass messages) {
myResult = MakeMyCall(inputParams, messages);
}
Once outside the using
block, messages
will be disposed automatically.
一旦出using
块,messages
将被自动处理。
回答by Jon Skeet
You have to declare a variable which you will then ignore. This is most commonly the case with the TryParse (or TryWhatever) pattern, when it is used to test the validity of user input (e.g. can it be parsed as a number?) without caring about the actual parsed value.
您必须声明一个变量,然后您将忽略该变量。这是 TryParse(或 TryWhatever)模式最常见的情况,当它用于测试用户输入的有效性(例如,可以将其解析为数字吗?)而不关心实际解析的值时。
You used the word "dispose" in the question, which I suspect was just unfortunate - but if the out parameter is of a type which implements IDisposable, you should certainly call Dispose unless the method documentation explicitly states that receiving the value doesn't confer ownership. I can't remember ever seeing a method with a disposable out
parameter though, so I'm hoping this was just an unlucky choice of words.
您在问题中使用了“dispose”这个词,我怀疑这很不幸——但是如果 out 参数是实现 IDisposable 的类型,那么您当然应该调用 Dispose,除非方法文档明确指出接收值不会赋予所有权。我不记得曾经见过带有一次性out
参数的方法,所以我希望这只是一个不幸的词选择。
回答by Joe Erickson
You must pass a variable for the out parameter. You do not have to initialize the variable before passing it:
您必须为 out 参数传递一个变量。您不必在传递变量之前对其进行初始化:
MyMessagesType messages;
myResult = MakeMyCall(inputParams, out messages);
Typically, you can just ignore 'messages' after the call - unless 'messages' needs disposing for some reason, such as the use of limited system resources, in which case you should call Dispose():
通常,您可以在调用后忽略“消息”——除非“消息”由于某种原因需要处理,例如使用有限的系统资源,在这种情况下,您应该调用 Dispose():
messages.Dispose();
If it might use a significant amount of memory and it is going to remain in scope for a while, it should probably be set to null if it is a reference type or to a new default instance if it's a value type, so that the garbage collector can reclaim the memory:
如果它可能使用大量内存并且将在范围内保留一段时间,如果它是引用类型,则可能应该将其设置为 null 或者如果它是值类型,则应将其设置为新的默认实例,以便垃圾收集器可以回收内存:
messages = null; // Allow GC to reclaim memory for reference type.
messages = new MyMessageType(); // Allow GC to reclaim memory for value type.
回答by Jonathan Allen
The Visual Basic compiler does this by creating a dummy variable. C# could do it, if you can convince Microsoft its a good idea.
Visual Basic 编译器通过创建一个虚拟变量来做到这一点。C# 可以做到,如果你能说服微软这是一个好主意。
回答by bmm6o
If the original function is declared like this:
如果原始函数是这样声明的:
class C
{
public Result MakeMyCall(Object arg, out List<String> messages);
}
You can declare an extension method like this:
您可以像这样声明一个扩展方法:
static class CExtension
{
public static Result MakeMyCall(this C obj, Object arg)
{
List<String> unused;
return obj.MakeMyCall(arg, out unused);
}
}
The extension method will behave like an overload that makes the out parameter optional.
扩展方法的行为类似于使 out 参数可选的重载。
回答by flodis
In this case I made an generic extension method for ConcurrentDictionary that has no Delete or Remove method.
在这种情况下,我为 ConcurrentDictionary 创建了一个没有 Delete 或 Remove 方法的通用扩展方法。
//Remove item from list and ignore reference to removed item
public static void TryRemoveIgnore<K,T>(this ConcurrentDictionary<K,T> dictionary, K key)
{
T CompletelyIgnored;
dictionary.TryRemove(key, out CompletelyIgnored);
}
When called from an instance of ConcurrentDictionary:
从 ConcurrentDictionary 的实例调用时:
ClientList.TryRemoveIgnore(client.ClientId);