valores una retornar retornan que multiples funciones funcion devolver como c# function return

c# - una - funciones que retornan valores en c++



¿Cómo puedo devolver múltiples valores de una función en C#? (25)

Algunas de estas respuestas indicaron que usan un parámetro, pero recomiendo no usar esto porque no funcionan con métodos asíncronos . Vea this para más información.

Otras respuestas indicaron el uso de Tuple, lo que recomendaría también, pero el uso de la nueva función introducida en C # 7.0.

private KeyValuePair<int, int> GetNumbers() { return new KeyValuePair<int, int>(1, 2); } var numbers = GetNumbers(); Console.WriteLine("Output : {0}, {1}",numbers.Key, numbers.Value);

Más información se puede encontrar here .

Leí la versión C ++ de esta pregunta, pero realmente no la entendí.

¿Puede alguien explicar claramente si se puede hacer y cómo?


A partir de this artículo, puedes usar tres opciones como se dijo en las publicaciones anteriores.

KeyValuePair es la forma más rápida.

fuera está en el segundo.

Tuple es el más lento.

De todos modos, esto depende de lo que sea mejor para su escenario.


Ahora que C # 7 ha sido lanzado, puede usar la nueva sintaxis de Tuples incluida

(string, string, string) LookupName(long id) // tuple return type { ... // retrieve first, middle and last from data storage return (first, middle, last); // tuple literal }

que luego podría ser usado de esta manera:

var names = LookupName(id); WriteLine($"found {names.Item1} {names.Item3}.");

También puede proporcionar nombres a sus elementos (por lo que no son "Item1", "Item2", etc.). Puede hacerlo agregando un nombre a la firma o los métodos de devolución:

(string first, string middle, string last) LookupName(long id) // tuple elements have names

o

return (first: first, middle: middle, last: last); // named tuple elements in a literal

También se pueden deconstruir, lo que es una nueva característica bastante buena:

(string first, string middle, string last) = LookupName(id1); // deconstructing declaration

Echa un vistazo a este enlace para ver más ejemplos de lo que se puede hacer :)


Aquí hay Two métodos básicos:

1) Uso de '' out '' como parámetro También puede usar ''out'' para versiones 4.0 y secundarias.

Ejemplo de ''out'':

using System; namespace out_parameter { class Program { //Accept two input parameter and returns two out value public static void rect(int len, int width, out int area, out int perimeter) { area = len * width; perimeter = 2 * (len + width); } static void Main(string[] args) { int area, perimeter; // passing two parameter and getting two returning value Program.rect(5, 4, out area, out perimeter); Console.WriteLine("Area of Rectangle is {0}/t",area); Console.WriteLine("Perimeter of Rectangle is {0}/t", perimeter); Console.ReadLine(); } } }

Salida:

Área del rectángulo es 20

El perímetro del rectángulo es 18

* Nota: * out keyword describe los parámetros cuyas ubicaciones de variables reales se copian en la pila del método llamado, donde se pueden reescribir esas mismas ubicaciones. Esto significa que el método de llamada tendrá acceso al parámetro modificado.

2) Tuple<T>

Ejemplo de tuple:

Devolviendo múltiples valores DataType usando Tuple<T>

using System; class Program { static void Main() { // Create four-item tuple; use var implicit type. var tuple = new Tuple<string, string[], int, int[]>("perl", new string[] { "java", "c#" }, 1, new int[] { 2, 3 }); // Pass tuple as argument. M(tuple); } static void M(Tuple<string, string[], int, int[]> tuple) { // Evaluate the tuple''s items. Console.WriteLine(tuple.Item1); foreach (string value in tuple.Item2) { Console.WriteLine(value); } Console.WriteLine(tuple.Item3); foreach (int value in tuple.Item4) { Console.WriteLine(value); } } }

Salida

perl java c# 1 2 3

NOTA: El uso de Tuple es válido desde Framework 4.0 y superior . Tuple tipo es una class . Se asignará en una ubicación separada en el montón administrado en la memoria. Una vez que creas la Tuple , no puedes cambiar los valores de sus fields . Esto hace que la Tuple parezca más a una struct .


El cartel anterior es correcto. No puede devolver varios valores desde un método C #. Sin embargo, tienes un par de opciones:

  • Devuelve una estructura que contiene múltiples miembros
  • Devuelve una instancia de una clase.
  • Usar parámetros de salida (usando las palabras clave out o ref )
  • Utilice un diccionario o un par clave-valor como salida

Los pros y los contras aquí son a menudo difíciles de entender. Si devuelve una estructura, asegúrese de que sea pequeña porque las estructuras son de tipo valor y se pasan a la pila. Si devuelve una instancia de una clase, aquí hay algunos patrones de diseño que tal vez quiera usar para evitar causar problemas: los miembros de las clases pueden modificarse porque C # pasa objetos por referencia (no tiene ByVal como lo hizo en VB). ).

Finalmente, puedes usar los parámetros de salida, pero limitaría el uso de esto a los escenarios cuando solo tengas un par (como 3 o menos) de parámetros; de lo contrario, las cosas se ponen feas y difíciles de mantener. Además, el uso de parámetros de salida puede ser un inhibidor de la agilidad porque la firma de su método tendrá que cambiar cada vez que necesite agregar algo al valor de retorno, mientras que al devolver una estructura o instancia de clase puede agregar miembros sin modificar la firma del método.

Desde un punto de vista arquitectónico, recomendaría no usar pares de clave-valor o diccionarios. Encuentro que este estilo de codificación requiere "conocimiento secreto" en el código que consume el método. Debe saber con anticipación cuáles serán las claves y qué significarán los valores, y si el desarrollador que trabaja en la implementación interna cambia la forma en que se crea el diccionario o KVP, podría crear fácilmente una cascada de fallos en toda la aplicación.


En C # 4, podrá usar el soporte incorporado para tuplas para manejar esto fácilmente.

Mientras tanto, hay dos opciones.

Primero, puede usar los parámetros ref o out para asignar valores a sus parámetros, que se transfieren nuevamente a la rutina de llamada.

Esto se ve como

void myFunction(ref int setMe, out int youMustSetMe);

En segundo lugar, puede resumir sus valores de retorno en una estructura o clase y devolverlos como miembros de esa estructura. KeyValuePair funciona bien para 2; para más de 2 necesitaría una clase o estructura personalizada.


En C # 7 hay una nueva sintaxis de Tuple :

static (string foo, int bar) GetTuple() { return ("hello", 5); }

Puede devolver esto como un registro:

var result = GetTuple(); var foo = result.foo // foo == "hello"

También puedes usar la nueva sintaxis de deconstructor:

(string foo) = GetTuple(); // foo == "hello"

Sin embargo, tenga cuidado con la serialización, todo esto es azúcar sintáctica: en el código compilado real será una Tupel<string, int> (según la respuesta aceptada ) con Item2 y Item2 lugar de foo y bar . Eso significa que la serialización (o deserialización) usará esos nombres de propiedad en su lugar.

Entonces, para la serialización, declare una clase de registro y devuelva eso en su lugar.

Otra novedad en C # 7 es una sintaxis mejorada para out parámetros de out . Ahora puede declarar el out inline, que es más adecuado en algunos contextos:

if(int.TryParse("123", out int result)) { // Do something with result }

Sin embargo, en su mayoría, utilizará esto en las propias bibliotecas de .NET, en lugar de hacerlo en sus propias funciones.


Hay varias formas de hacerlo. Puede utilizar los parámetros de ref :

int Foo(ref Bar bar) { }

Esto pasa una referencia a la función, lo que permite a la función modificar el objeto en la pila del código que llama. Si bien esto no es técnicamente un valor "devuelto", es una forma de hacer que una función haga algo similar. En el código anterior, la función devolverá una bar modificación int y (potencialmente).

Otro enfoque similar es utilizar un parámetro de out . Un parámetro de out es idéntico a un parámetro de ref con una regla adicional impuesta por el compilador. Esta regla es que si pasa un parámetro a una función, esa función es necesaria para establecer su valor antes de regresar. Además de esa regla, un parámetro de out funciona igual que un parámetro de ref .

El enfoque final (y el mejor en la mayoría de los casos) es crear un tipo que encapsule ambos valores y permitir que la función devuelva eso:

class FooBar { public int i { get; set; } public Bar b { get; set; } } FooBar Foo(Bar bar) { }

Este enfoque final es más simple y más fácil de leer y entender.


Hoy en día, los programadores necesitan tiempo y métodos inolvidables. Una solución simple, operativa y rápida:

private int[] SumAndSub(int A, int B) { return new[] { A + B , A - B }; }

Usándolo en algún lugar;

int sum = SumAndSub(20, 5)[0]; int sub = SumAndSub(20, 5)[1];


La versión futura de C # incluirá tuplas con nombre. Eche un vistazo a esta sesión de channel9 para la demostración https://channel9.msdn.com/Events/Build/2016/B889

Salta a las 13:00 para las cosas de la tupla. Esto permitirá cosas como:

(int sum, int count) Tally(IEnumerable<int> list) { // calculate stuff here return (0,0) } int resultsum = Tally(numbers).sum

(Ejemplo incompleto del video)


Las clases, estructuras, colecciones y matrices pueden contener múltiples valores. Los parámetros de salida y de referencia también se pueden configurar en una función. Devolver múltiples valores es posible en lenguajes dinámicos y funcionales por medio de tuplas, pero no en C #.


Maneras de hacerlo:

1) KeyValuePair (Mejor rendimiento - 0.32 ns):

KeyValuePair<int, int> Location(int p_1, int p_2, int p_3, int p_4) { return new KeyValuePair<int,int>(p_2 - p_1, p_4-p_3); }

2) Tuple - 5.40 ns:

Tuple<int, int> Location(int p_1, int p_2, int p_3, int p_4) { return new Tuple<int, int>(p_2 - p_1, p_4-p_3); }

3) out (1.64 ns) o ref 4) Crea tu propia clase / estructura personalizada

ns -> nanosegundos

Referencia: this .


No puedes hacer esto en C #. Lo que puedes hacer es tener un parámetro de out o devolver tu propia clase (o estructura si quieres que sea inmutable).

Usando el parámetro

public int GetDay(DateTime date, out string name) { // ... } Usando clase personalizada (o estructura)

public DayOfWeek GetDay(DateTime date) { // ... } public class DayOfWeek { public int Day { get; set; } public string Name { get; set; } }


No, no puede devolver varios valores de una función en C # (para versiones inferiores a C # 7), al menos no de la forma en que puede hacerlo en Python.

Sin embargo, hay un par de alternativas:

Puede devolver una matriz de tipo objeto con los múltiples valores que desea en ella.

private object[] DoSomething() { return new [] { ''value1'', ''value2'', 3 }; }

Puede utilizar out parámetros.

private string DoSomething(out string outparam1, out int outparam2) { outparam1 = ''value2''; outparam2 = 3; return ''value1''; }


Podrías usar un objeto dinámico. Creo que tiene mejor legibilidad que Tuple.

static void Main(string[] args){ var obj = GetMultipleValues(); Console.WriteLine(obj.Id); Console.WriteLine(obj.Name); } private static dynamic GetMultipleValues() { dynamic temp = new System.Dynamic.ExpandoObject(); temp.Id = 123; temp.Name = "Lorem Ipsum"; return temp; }


Principalmente hay dos métodos. 1. Usar los parámetros de out / ref 2. Devolver una matriz de objetos


Puede devolver una instancia de clase o usar parámetros. Aquí hay un ejemplo de los parámetros de salida:

void mymethod(out int param1, out int param2) { param1 = 10; param2 = 20; }

Llámalo así:

int i, j; mymethod(out i, out j); // i will be 20 and j will be 10


Puedes probar este "KeyValuePair"

(string, string, string) LookupName(long id) // tuple return type { ... // retrieve first, middle and last from data storage return (first, middle, last); // tuple literal } var names = LookupName(id); WriteLine($"found {names.Item1} {names.Item3}.");

Salida:

Salida: 1, 2


Puedes usar tres formas diferentes

1. parámetros de ref / out

utilizando ref:

static void Main(string[] args) { int a = 10; int b = 20; int add = 0; int multiply = 0; Add_Multiply(a, b, ref add, ref multiply); Console.WriteLine(add); Console.WriteLine(multiply); } private static void Add_Multiply(int a, int b, ref int add, ref int multiply) { add = a + b; multiply = a * b; }

usando fuera

static void Main(string[] args) { int a = 10; int b = 20; int add; int multiply; Add_Multiply(a, b, out add, out multiply); Console.WriteLine(add); Console.WriteLine(multiply); } private static void Add_Multiply(int a, int b, out int add, out int multiply) { add = a + b; multiply = a * b; }

2. estructura / clase

usando struct:

struct Result { public int add; public int multiply; } static void Main(string[] args) { int a = 10; int b = 20; var result = Add_Multiply(a, b); Console.WriteLine(result.add); Console.WriteLine(result.multiply); } private static Result Add_Multiply(int a, int b) { var result = new Result { add = a * b, multiply = a + b }; return result; }

usando la clase:

class Result { public int add; public int multiply; } static void Main(string[] args) { int a = 10; int b = 20; var result = Add_Multiply(a, b); Console.WriteLine(result.add); Console.WriteLine(result.multiply); } private static Result Add_Multiply(int a, int b) { var result = new Result { add = a * b, multiply = a + b }; return result; }

3. Tuple

Clase de tupla

static void Main(string[] args) { int a = 10; int b = 20; var result = Add_Multiply(a, b); Console.WriteLine(result.Item1); Console.WriteLine(result.Item2); } private static Tuple<int, int> Add_Multiply(int a, int b) { var tuple = new Tuple<int, int>(a + b, a * b); return tuple; }

Tuples C # 7

static void Main(string[] args) { int a = 10; int b = 20; (int a_plus_b, int a_mult_b) = Add_Multiply(a, b); Console.WriteLine(a_plus_b); Console.WriteLine(a_mult_b); } private static (int a_plus_b, int a_mult_b) Add_Multiply(int a, int b) { return(a + b, a * b); }


Si te refieres a devolver varios valores, puedes devolver una clase / estructura que contenga los valores que deseas devolver o usar la palabra clave "out" en tus parámetros, de esta forma:

public void Foo(int input, out int output1, out string output2, out string errors) { // set out parameters inside function }


Solo usa en modo OOP una clase como esta:

class div { public int remainder; public int quotient(int dividend, int divisor) { remainder = ...; return ...; } }

El miembro de la función devuelve el cociente en el que están interesados ​​principalmente la mayoría de las personas que llaman. Además, almacena el resto como un miembro de datos, que luego es fácilmente accesible para la persona que llama.

De esta manera, puede tener muchos "valores de retorno" adicionales, muy útiles si implementa llamadas de base de datos o de red, donde se pueden necesitar muchos mensajes de error, pero solo en caso de que ocurra un error.

Ingresé a esta solución también en la pregunta de C ++ a la que se refiere OP.


También puedes usar un OperationResult

public OperationResult DoesSomething(int number1, int number2) { // Your Code var returnValue1 = "return Value 1"; var returnValue2 = "return Value 2"; var operationResult = new OperationResult(returnValue1, returnValue2); return operationResult; }


Un método que toma un delegado puede proporcionar múltiples valores a la persona que llama. Esto se toma de mi respuesta here y utiliza un poco de la respuesta aceptada de Hadas .

delegate void ValuesDelegate(int upVotes, int comments); void GetMultipleValues(ValuesDelegate callback) { callback(1, 2); }

Las personas que llaman proporcionan una lambda (o una función nombrada) y ayuda inteligente al copiar los nombres de las variables del delegado.

GetMultipleValues((upVotes, comments) => { Console.WriteLine($"This post has {upVotes} Up Votes and {comments} Comments."); });


Use .NET 4.0 + ''s Tuple :

Por ejemplo:

public Tuple<int, int> GetMultipleValue() { return Tuple.Create(1,2); }

Las tuplas con dos valores tienen Item2 y Item2 como propiedades.


puedes probar esto

public IEnumerable<string> Get() { return new string[] { "value1", "value2" }; }