如何显式放弃输出参数?

我打个电话:

myResult = MakeMyCall(inputParams, out messages);

但其实我并不在乎那些信息。如果它是一个我不关心的输入参数,我只需要传入一个 null。如果是我不在乎的回报,我就不管了。

有没有一种方法可以用 out 来做类似的事情,或者我需要声明一个变量,然后忽略它?

44372 次浏览

不幸的是,您需要传递某些内容,因为需要该方法来设置它。因此,您不能发送 null,因为设置它所需的方法会崩溃。

一种隐藏丑陋的方法是将该方法包装在另一个方法中,该方法为您执行 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.

如果 messages的类实现了 IDisposable,则不应忽略它。考虑下面这种方法(可能语法不正确,因为我有一段时间没有编写 C # 了) :

using (FooClass messages) {
myResult = MakeMyCall(inputParams, messages);
}

一旦离开 using区块,messages将被自动释放。

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.

您在问题中使用了“ pose”这个词,我怀疑这只是一种不幸——但是如果 out 参数属于实现 IDisposable 的类型,那么您当然应该调用 Dispose,除非方法文档明确指出接收值并不意味着所有权。但是我不记得曾经看到过使用一次性 out参数的方法,所以我希望这只是一个不幸的选择。

必须为 out 参数传递一个变量。在传递变量之前不必初始化它:

MyMessagesType messages;
myResult = MakeMyCall(inputParams, out messages);

通常,您可以忽略调用后的“消息”——除非由于某种原因(如使用有限的系统资源)需要处理“消息”,在这种情况下,您应该调用 Dispose () :

messages.Dispose();

如果它可能使用大量的内存,并且要在作用域中停留一段时间,那么如果它是引用类型,那么它可能应该被设置为 null; 如果它是值类型,那么它应该被设置为新的默认实例,这样垃圾收集器就可以回收内存:

messages = null; // Allow GC to reclaim memory for reference type.


messages = new MyMessageType(); // Allow GC to reclaim memory for value type.

VisualBasic 编译器通过创建一个虚拟变量来实现这一点。C # 可以做到这一点,如果你能说服微软这是个好主意的话。

If the original function is declared like this:

class C
{
public Result MakeMyCall(Object arg, out List<String> messages);
}

可以像下面这样声明扩展方法:

static class CExtension
{
public static Result MakeMyCall(this C obj, Object arg)
{
List<String> unused;
return obj.MakeMyCall(arg, out unused);
}
}

扩展方法的行为将类似于使 out 参数成为可选的重载。

从 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}");
}

资料来源: https://blogs.msdn.microsoft.com/dotnet/2017/03/09/new-features-in-c-7-0/

在本例中,我为 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);
}

当从 ConcurrentDictionary 的实例调用时:

ClientList.TryRemoveIgnore(client.ClientId);