referencia programacion por pasar pasaje parametros opcionales objetos metodos funciones como clases c# out

c# - programacion - ¿Cómo descartar explícitamente un argumento de salida?



pasar objetos como parametros en c# (8)

Comenzando con C # 7.0, es posible evitar predefinir los parámetros e ignorarlos.

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

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

Estoy haciendo una llamada:

myResult = MakeMyCall(inputParams, out messages);

pero en realidad no me importan los mensajes. Si fuera un parámetro de entrada que no me importara, simplemente pasaría un nulo. Si fuera la devolución lo que no me importaba, simplemente lo dejaría.

¿Hay alguna manera de hacer algo similar con una salida, o debo declarar una variable que luego ignoraré?


Debe declarar una variable que luego ignorará. Este suele ser el caso con el patrón TryParse (o TryWhatever), cuando se utiliza para probar la validez de la entrada del usuario (por ejemplo, ¿se puede analizar como un número?) Sin preocuparse por el valor analizado real.

Usó la palabra "dispose" en la pregunta, que sospecho que fue desafortunado, pero si el parámetro out es de un tipo que implemente IDisposable, debe llamar a Dispose a menos que la documentación del método indique explícitamente que no recibe el valor. propiedad. Sin embargo, no recuerdo haber visto un método con un parámetro desechable, así que espero que esta sea una mala elección de palabras.


Debe pasar una variable para el parámetro de salida. No es necesario inicializar la variable antes de pasarla:

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

Normalmente, puede ignorar ''mensajes'' después de la llamada, a menos que ''mensajes'' necesite deshacerse por algún motivo, como el uso de recursos limitados del sistema, en cuyo caso debe llamar a Dispose ():

messages.Dispose();

Si podría usar una cantidad significativa de memoria y permanecerá en el alcance por un tiempo, probablemente debería establecerse en nulo si es un tipo de referencia o una nueva instancia predeterminada si es un tipo de valor, de modo que la basura el coleccionista puede reclamar la memoria:

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


El compilador de Visual Basic hace esto al crear una variable ficticia. C # podría hacerlo, si puede convencer a Microsoft es una buena idea.


En este caso, hice un método de extensión genérico para ConcurrentDictionary que no tiene ningún método de Eliminar o Eliminar.

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

Cuando se llama desde una instancia de ConcurrentDictionary:

ClientList.TryRemoveIgnore(client.ClientId);


Lamentablemente, se le exige pasar algo porque se requiere el método para configurarlo. Por lo tanto, no puede enviar un null porque el método, al estar obligado a configurarlo, explotaría.

Un enfoque para ocultar lo feo sería envolver el método en otro método que haga lo mismo out parámetro out :

String Other_MakeMyCall(String inputParams) { String messages; return MakeMyCall(inputParams, out messages); }

Luego puede llamar a Other_MakeMyCall sin tener que Other_MakeMyCall parámetros que no necesita.


Si la clase de messages implementa IDisposable , no debe ignorarla. Considere algo como el siguiente enfoque (puede no ser sintácticamente correcto ya que no he escrito C # por un tiempo):

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

Una vez fuera del bloque de using , los messages se eliminarán automáticamente.


Si la función original se declara así:

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

Puede declarar un método de extensión como este:

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

El método de extensión se comportará como una sobrecarga que hace que el parámetro de salida sea opcional.