Domanda

Sto effettuando una chiamata:

myResult = MakeMyCall(inputParams, out messages);

ma in realtà non mi importa dei messaggi. Se fosse un parametro di input di cui non mi importavo, passerei un valore null. Se fosse il ritorno a cui non mi importava, lo lascerei semplicemente.

Esiste un modo per fare qualcosa di simile con un out o devo dichiarare una variabile che poi ignorerò?

È stato utile?

Soluzione

A partire da C # 7.0, è possibile evitare di predire i parametri e ignorarli.

public void PrintCoordinates(Point p)
{
    p.GetCoordinates(out int x, out int y);
    WriteLine(<*>quot;({x}, {y})");
}

public void PrintXCoordinate(Point p)
{
    p.GetCoordinates(out int x, out _); // I only care about x
    WriteLine(<*>quot;{x}");
}

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

Altri suggerimenti

Devi dichiarare una variabile che poi ignorerai. Questo è più comunemente il caso del modello TryParse (o TryWhatever), quando viene utilizzato per testare la validità dell'input dell'utente (ad es. Può essere analizzato come un numero?) Senza preoccuparsi dell'effettivo valore analizzato.

Hai usato la parola " dispose " nella domanda, che sospetto fosse semplicemente sfortunata, ma se il parametro out è di un tipo che implementa IDisposable, dovresti certamente chiamare Dispose a meno che la documentazione del metodo non dichiari esplicitamente che la ricezione del valore non conferisce la proprietà. Non ricordo di aver mai visto un metodo con un parametro out usa e getta, quindi spero che sia stata solo una sfortunata scelta di parole.

Sfortunatamente ti viene richiesto di passare qualcosa perché il metodo è necessario per impostarlo. Quindi non puoi inviare null perché il metodo, richiesto per impostarlo, esploderà.

Un approccio per nascondere la bruttezza sarebbe quello di avvolgere il metodo in un altro metodo che fa il parametro out per te in questo modo:

String Other_MakeMyCall(String inputParams)
{
    String messages;

    return MakeMyCall(inputParams, out messages);
}

Quindi puoi chiamare Other_MakeMyCall senza dover giocherellare con i parametri out che non ti servono.

Se la funzione originale è dichiarata in questo modo:

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

Puoi dichiarare un metodo di estensione come questo:

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

Il metodo di estensione si comporterà come un sovraccarico che rende facoltativo il parametro out.

Il compilatore di Visual Basic fa ciò creando una variabile fittizia. C # potrebbe farlo, se riesci a convincere Microsoft che è una buona idea.

Se la classe di messaggi implementa IDisposable , non dovresti ignorarlo. Considera qualcosa come il seguente approccio (potrebbe non essere sintatticamente corretto poiché non scrivo C # da un po '):

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

Una volta fuori dal blocco utilizzando , i messaggi verranno eliminati automaticamente.

È necessario passare una variabile per il parametro out. Non è necessario inizializzare la variabile prima di passarla:

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

In genere, puoi semplicemente ignorare i "messaggi" dopo la chiamata, a meno che non sia necessario disporre di "messaggi" per qualche motivo, come l'uso di risorse di sistema limitate, nel qual caso dovresti chiamare Dispose ():

messages.Dispose();

Se potrebbe utilizzare una quantità significativa di memoria e rimarrà nell'ambito per un po ', probabilmente dovrebbe essere impostato su null se è un tipo di riferimento o su una nuova istanza predefinita se è un tipo di valore, quindi che il Garbage Collector può recuperare la memoria:

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

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

In questo caso ho creato un metodo di estensione generico per ConcurrentDictionary che non ha un metodo Elimina o Rimuovi.

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

Quando chiamato da un'istanza di ConcurrentDictionary:

ClientList.TryRemoveIgnore(client.ClientId);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top