Pregunta

yo leo el Versión C++ de esta pregunta pero realmente no lo entendí.

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

¿Fue útil?

Solución

.NET 4.0 + 's Tupla :

Por ejemplo:

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

tuplas con dos valores han Item1 y Item2 como propiedades.

Otros consejos

Ahora que C # 7 ha sido puesto en libertad, puede utilizar la nueva sintaxis Tuplas incluido

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

que podría entonces ser utilizada como esta:

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

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

(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 pueden ser deconstruido, que es una bonita característica nueva:

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

este vincular para ver más ejemplos de lo que se puede hacer:)

Puede utilizar tres formas diferentes

1. árbitro de entrada / salida parámetros

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

utilizando Salida:

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. struct / 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. Tupla

clase Tuple

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

C # 7 tuplas

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

No se puede hacer esto en C #. Lo que puede hacer es tener un parámetro out o regresar a su propia clase (o estructura si se quiere que sea inmutable).

Usando cabo parámetro
public int GetDay(DateTime date, out string name)
{
  // ...
}
El uso de clase personalizada (o estructura)
public DayOfWeek GetDay(DateTime date)
{
  // ...
}

public class DayOfWeek
{
  public int Day { get; set; }
  public string Name { get; set; }
}

Si se refiere a devolver varios valores, puede devolver una clase / estructura que contiene los valores que desea devolver o utilizar la palabra clave "fuera" en sus parámetros, así:

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

comentario anterior es correcta. No se puede devolver varios valores de un método de C #. Sin embargo, usted tiene un par de opciones:

  • Vuelta una estructura que contiene varios miembros
  • devolver una instancia de una clase
  • Uso parámetros de salida (utilizando el a cabo o ref palabras clave)
  • Use un diccionario o 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 de valor y se pasa a la pila. Si devuelve una instancia de una clase, hay algunos patrones de diseño aquí que es posible que desee utilizar para evitar causar problemas - los miembros de las clases pueden ser modificados debido a que C # pasa objetos de referencia (que no tiene ByVal como lo hizo en VB ).

Por último, puede utilizar los parámetros de salida pero me gustaría limitar el uso de los escenarios cuando sólo tiene 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 debido a que su firma del método tendrá que cambiar cada vez que es necesario agregar algo para el valor de retorno mientras que devolver una instancia de estructura o clase puede agregar miembros sin modificar la firma del método.

Desde un punto de vista arquitectónico recomendaría contra el uso de pares de valores clave o diccionarios. Me parece que este estilo de codificación requiere "conocimiento secreto" en el código que consume el método. Debe saber de antemano cuáles son las claves van a ser y cuáles son los valores medios y si el desarrollador que trabaja en la implementación interna cambia la forma en que el diccionario o se crea KVP, que fácilmente podrían crear una cascada de fallos en toda la aplicación.

o bien devolver un instancia de clase o usa a cabo parámetros. He aquí un ejemplo de los parámetros de salida:

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

Llamada así:

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

Hay varias maneras de hacer esto. Puede utilizar los parámetros ref:

int Foo(ref Bar bar) { }

Esta pasa una referencia a la función permitiendo de este modo la función de modificar el objeto en la pila del código de llamada. Si bien esto no es técnicamente un valor "devolvió" es una manera de tener una función de hacer algo similar. En el código anterior la función devolverá un int y (potencialmente) modificar bar.

Otro enfoque similar es utilizar un parámetro out. Un parámetro out es idéntico a un parámetro ref con una regla adicional, compilador forzada. Esta regla es que si pasa un parámetro out en una función, se requiere que la función para establecer su valor antes de la devolución. Además de esa regla, un parámetro out funciona como un parámetro ref.

La aproximación final (y la mejor en muchos casos) es la creación de un tipo que encapsula ambos valores y permitir que la función devuelva lo siguiente:

class FooBar 
{
    public int i { get; set; }
    public Bar b { get; set; }
}

FooBar Foo(Bar bar) { }

Esta aproximación final es más simple y más fácil de leer y entender.

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

Sin embargo, hay un par de alternativas:

Puede devolver una matriz de tipo de objeto con los valores múltiples que desee en el mismo.

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

Puede utilizar parámetros out.

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

En C # 4, usted será capaz de utilizar el soporte incorporado para tuplas para manejar esto fácilmente.

Mientras tanto, hay dos opciones.

En primer lugar, puede utilizar ref o fuera parámetros para asignar valores a sus parámetros, que van pasando de nuevo a la rutina de llamada.

Esto es así:

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

En segundo lugar, se puede concluir sus valores de retorno en una estructura o clase, y pasar de nuevo como miembros de esa estructura. KeyValuePair funciona bien para 2 -. Durante más de 2 se necesitaría una clase personalizada o estructura

En C # 7 Hay una nueva sintaxis Tuple:

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

Puede volver esto como un registro:

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

También puede utilizar la nueva sintaxis Deconstructor:

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

Tenga cuidado con la serialización sin embargo, todo esto es el azúcar sintáctica - en el código compilado real de que este será un Tupel<string, int> (como por el aceptada respuesta) con Item1 y Item2 en lugar de foo y bar. Eso significa que la serialización (o deserialización) usarán los nombres de las propiedades en su lugar.

Por lo tanto, para la serialización declarar una clase registro y regresar en su lugar.

También nuevo en C # 7 es una sintaxis mejorado para parámetros out. Ahora puede declarar la línea out, que se adapta mejor en algunos contextos:

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

Sin embargo, la mayoría va a utilizar en esta propias bibliotecas de .NET, y no en funciones es el propietario.

  

Algunas respuestas sugieren el uso de a cabo parámetros pero recomiendo   no usar esto debido a no trabajan con métodos asincrónicos . Ver    este para más información.

Otras respuestas indicaron usando Tupla, que se lo recomendaría también, pero el uso de la nueva característica introducida en C # 7.0.

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

Más información se puede encontrar aquí .

puede probar esta "KeyValuePair"

private KeyValuePair<int, int> GetNumbers()
{
  return new KeyValuePair<int, int>(1, 2);
}


var numbers = GetNumbers();

Console.WriteLine("Output : {0}, {1}",numbers.Key, numbers.Value);

Salida:

Salida: 1, 2

Las clases, estructuras, colecciones y matrices pueden contener varios 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 los lenguajes dinámicos y funcionales por medio de tuplas, pero no en C #.

principalmente dos métodos son allí. 1. Utilice cabo parámetros / ref 2. devolver una matriz de objetos

Estos son métodos básicos Two:

1) Uso de 'out' como parámetro Puede usar 'fuera' para ambas versiones 4.0 y menores también.

Ejemplo de 'fuera':

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

Perímetro del rectángulo es 18

* Nota: * La out-palabra clave describe cuyos parámetros variables reales ubicaciones se copian en la pila del método llamado, donde esos mismos lugares se pueden reescribir. Esto significa que el método de llamada accederá al parámetro modificado.

2) Tuple<T>

Ejemplo de tupla:

Volviendo valores DataType múltiple utilizando 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: Uso de la tupla es válida desde el marco 4.0 y superior Tipo de .Tuple es una class. Este se le asignará en un lugar separado en el montón administrado en la memoria. Una vez creado el Tuple, no se puede cambiar los valores de su fields. Esto hace que el Tuple más como un struct.

Un método de tomar un delegado puede proporcionar múltiples valores a la persona que llama. Esta toma prestado de mi respuesta aquí y utiliza un poco de Hadas de respuesta aceptada .

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 llamada) y intelisense ayuda copiando los nombres de las variables del delegado.

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

Sólo tiene que utilizar de manera POO una clase como esta:

class div
{
    public int remainder;

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

El miembro de función devuelve el cociente de la cual la mayoría de las personas que llaman son principalmente interese. Además se almacena el resto como un miembro de datos, que es fácilmente accesible por la persona que llama después.

De esta manera usted puede tener muchos "valores de retorno" adicionales, muy útil si la aplicación de base de datos o redes de llamadas, donde podrían necesitarse muchos mensajes de error, pero sólo en caso de que se produzca un error.

entré en esta solución también en la cuestión de C ++ que la OP se refiere.

este artículo , puede utilizar tres opciones como puestos por encima de dicha.

KeyValuePair es forma más rápida.

fuera está en el segundo.

Tuple es el más lento.

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

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

Saltar a 13:00 para la materia de 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 incompleta de video)

Se puede usar un objeto dinámico. Creo que tiene una mejor legibilidad de tupla.

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;
}
<--Return more statements like this you can --> 

public (int,string,etc) Sample( int a, int b)  
{
    //your code;
    return (a,b);  
}

Puede recibir un código como

(c,d,etc) = Sample( 1,2);

espero que funcione.

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) hacia fuera (1,64 ns) o ref 4) Cree su propia clase personalizada / struct

ns -> nanosegundos

Referencia: valores múltiples de retorno

.

puedes probar esto

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

También puede utilizar 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;
}

Hay muchas maneras; pero si usted no desea crear un nuevo objeto o estructura o algo como esto se puede hacer, como a continuación después de C # 7.0 :

 (string firstName, string lastName) GetName(string myParameter)
    {
        var firstName = myParameter;
        var lastName = myParameter + " something";
        return (firstName, lastName);
    }

    void DoSomethingWithNames()
    {
        var (firstName, lastName) = GetName("myname");

    }

Hoy en día, los programadores necesitan tiempo y métodos Unforgotable. Una solución sencilla, rápida y de trabajo:

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

Su uso en algún lugar;

var results = SumAndSub(20, 5);
int sum = results[0];
int sub = results[0];
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top