Есть ли способ просто не беспокоить параметр out в С#?

Я звоню:

myResult = MakeMyCall(inputParams, out messages);

но я действительно не забочусь о сообщениях. Если бы это был входной параметр, мне все равно, что я просто передаю нуль. Если бы это было возвращение, мне было все равно, что я просто оставлю это.

Есть ли способ сделать что-то подобное с out, или мне нужно объявить переменную, которую я проигнорирую?

Ответ 1

Начиная с С# 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/

Ответ 2

Вы должны объявить переменную, которую вы проигнорируете. Это чаще всего происходит с шаблоном TryParse (или TryWhatever), когда он используется для проверки достоверности ввода пользователя (например, может ли он анализироваться как число?), Не заботясь о фактическом анализируемом значении.

В вопросе вы использовали слово "dispose", которое, как я подозреваю, было просто неудачным, но если параметр out имеет тип, который реализует IDisposable, вы должны обязательно вызвать Dispose, если в документации метода явно не указано, что получение значения doesn 't передать права собственности. Я не могу вспомнить, когда-либо видел метод с одноразовым параметром out, хотя, поэтому я надеюсь, что это был просто неудачный выбор слов.

Ответ 3

К сожалению, вам необходимо передать что-то, потому что для его установки требуется метод. Поэтому вы не можете отправить null, потому что метод, требуемый для его установки, взорвется.

Один из способов скрыть уродство - это обернуть метод в другом методе, который делает для него параметр out:

String Other_MakeMyCall(String inputParams)
{
    String messages;

    return MakeMyCall(inputParams, out messages);
}

Затем вы можете вызвать Other_MakeMyCall, не требуя параметров out, которые вам не нужны.

Ответ 4

Если оригинальная функция объявлена ​​следующим образом:

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.

Ответ 5

Компилятор Visual Basic делает это, создавая фиктивную переменную. С# может это сделать, если вы можете убедить Microsoft в своей хорошей идее.

Ответ 6

Вы должны передать переменную для параметра 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

В этом случае я сделал общий метод расширения для ConcurrentDictionary, который не имеет метода удаления или удаления.

//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);

Ответ 8

Если класс messages реализует IDisposable, вы не должны его игнорировать. Рассмотрим что-то вроде следующего подхода (возможно, не синтаксически корректно, так как я не написал С# через некоторое время):

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

Как только внешний блок using, messages будет удален автоматически.