it-swarm.com.de

Wie kann man ein Argument aus dem Spiel explizit verwerfen?

Ich mache einen Anruf:

myResult = MakeMyCall(inputParams, out messages);

aber die Nachrichten interessieren mich eigentlich nicht. Wenn es ein Eingabeparameter war, der mich nicht interessierte, würde ich einfach eine Null übergeben. Wenn es die Rückkehr war, die mich nicht interessierte, würde ich sie einfach auslassen. 

Gibt es eine Möglichkeit, etwas Ähnliches mit einem out zu tun, oder muss ich eine Variable deklarieren, die ich dann ignorieren werde?

75
Andrew Ducker

Beginnend mit C # 7.0 ist es möglich, zu vermeiden, dass Parameter heraus deklariert und ignoriert werden.

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

Quelle: https://blogs.msdn.Microsoft.com/dotnet/2017/03/09/new-features-in-c-7-0/

64
Nolonar

Sie müssen eine Variable deklarieren, die Sie dann ignorieren. Dies ist meistens beim TryParse-Muster (oder TryWhatever-Muster) der Fall, wenn es zum Testen der Gültigkeit von Benutzereingaben verwendet wird (z. B. kann es als Zahl geparst werden?), Ohne sich um den tatsächlich geparsten Wert zu kümmern.

Sie haben das Wort "dispose" in der Frage verwendet, von der ich vermute, dass sie nur unglücklich war. Wenn der out-Parameter jedoch von einem Typ ist, der IDisposable implementiert, sollten Sie unbedingt Dispose aufrufen, es sei denn, in der Methodendokumentation wird ausdrücklich angegeben, dass der Wert nicht gegeben wird Eigentum. Ich kann mich nicht erinnern, jemals eine Methode mit einem verfügbaren out-Parameter gesehen zu haben, also hoffe ich, dass dies nur eine unglückliche Wortwahl war.

37
Jon Skeet

Leider müssen Sie etwas übergeben, da die Methode zum Festlegen der Methode erforderlich ist. Sie können also keine null senden, da die zum Einstellen erforderliche Methode explodieren würde.

Eine Möglichkeit, die Hässlichkeit zu verbergen, besteht darin, die Methode in eine andere Methode einzuwickeln, die den out-Parameter für Sie so macht:

String Other_MakeMyCall(String inputParams)
{
    String messages;

    return MakeMyCall(inputParams, out messages);
}

Dann können Sie Other_MakeMyCall aufrufen, ohne mit out-Parametern arbeiten zu müssen, die Sie nicht benötigen.

36
Andrew Hare

Wenn die ursprüngliche Funktion folgendermaßen deklariert ist:

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

Sie können eine Erweiterungsmethode folgendermaßen deklarieren:

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

Die Erweiterungsmethode verhält sich wie eine Überladung, die den out-Parameter optional macht.

11
bmm6o

Der Visual Basic-Compiler erstellt dies, indem er eine Dummy-Variable erstellt. C # könnte es tun, wenn Sie Microsoft überzeugen können, ist es eine gute Idee.

4
Jonathan Allen

In diesem Fall habe ich eine generische Erweiterungsmethode für ConcurrentDictionary erstellt, die keine Delete- oder Remove-Methode hat.

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

Bei Aufruf aus einer Instanz von ConcurrentDictionary:

ClientList.TryRemoveIgnore(client.ClientId);
0
flodis

Wenn die Klasse von messagesIDisposable implementiert, sollten Sie sie nicht ignorieren. Betrachten Sie etwas wie den folgenden Ansatz (möglicherweise nicht syntaktisch korrekt, da ich seit einiger Zeit kein C # geschrieben habe):

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

Außerhalb des using-Blocks wird messages automatisch gelöscht.

0
Sören Kuklau

Sie müssen eine Variable für den Parameter out übergeben. Sie müssen die Variable nicht initialisieren, bevor Sie sie übergeben:

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

Normalerweise können Sie nach dem Anruf einfach "Nachrichten" ignorieren - es sei denn, "Nachrichten" muss aus irgendeinem Grund entsorgt werden, z. B. aufgrund begrenzter Systemressourcen. In diesem Fall sollten Sie Dispose () aufrufen:

messages.Dispose();

Wenn es eine beträchtliche Menge an Speicherplatz benötigt und es für eine Weile im Gültigkeitsbereich verbleibt, sollte es wahrscheinlich auf null gesetzt werden, wenn es sich um einen Referenztyp handelt, oder auf eine neue Standardinstanz, wenn es sich um einen Werttyp handelt, so dass der Papierkorb verwendet wird Sammler kann den Speicher abrufen:

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

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