我正在打电话:
myResult = MakeMyCall(inputParams, out messages);
但我实际上并不关心这些消息。如果它是一个输入参数我不关心我只是传入一个null。如果是回归我不关心我只是把它关掉。
有没有办法用out做类似的事情,或者我是否需要声明一个我将忽略的变量?
答案 0 :(得分:69)
从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/
答案 1 :(得分:37)
您必须声明一个您将忽略的变量。最常见的情况是TryParse(或TryWhatever)模式,当它用于测试用户输入的有效性时(例如,它可以解析为数字吗?)而不关心实际的解析值。
你在问题中使用了“dispose”这个词,我怀疑这是不幸的 - 但是如果out参数是一个实现IDisposable的类型,你当然应该调用Dispose,除非方法文档明确指出接收值没有不授予所有权。我不记得曾经看过一个带有一次性out
参数的方法,所以我希望这只是一个不吉利的选择。
答案 2 :(得分:36)
不幸的是,您需要传递一些东西,因为需要设置它的方法。所以你不能发送null
,因为设置它的方法会爆炸。
隐藏丑陋的一种方法是将方法包装在另一个为您执行out
参数的方法中:
String Other_MakeMyCall(String inputParams)
{
String messages;
return MakeMyCall(inputParams, out messages);
}
然后,您可以拨打Other_MakeMyCall
,而不必使用您不需要的out
参数。
答案 3 :(得分:11)
如果原始函数声明如下:
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参数可选的重载。
答案 4 :(得分:4)
Visual Basic编译器通过创建虚拟变量来完成此操作。如果你能说服微软一个好主意,C#就可以做到。
答案 5 :(得分:0)
如果messages
的类实现IDisposable
,则不应忽略它。考虑类似下面的方法(可能在语法上不正确,因为我有一段时间没有编写C#):
using (FooClass messages) {
myResult = MakeMyCall(inputParams, messages);
}
一旦在using
区块之外,messages
将自动处理。
答案 6 :(得分:0)
您必须为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.
答案 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);