Возврат нескольких значений вызывающему методу - PullRequest
358 голосов
/ 14 апреля 2009

Я прочитал C ++ версию этого вопроса , но не совсем понял.

Может кто-нибудь объяснить, понятно, можно ли это сделать и как?

Ответы [ 26 ]

8 голосов
/ 09 марта 2017

В C # 7 есть новый синтаксис Tuple:

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

Вы можете вернуть это как запись:

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

Вы также можете использовать новый синтаксис деконструктора:

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

Будьте осторожны с сериализацией, однако все это синтаксический сахар - в фактическом скомпилированном коде это будет Tupel<string, int> (как за принятый ответ ) с Item1 и Item2 вместо foo и bar. Это означает, что сериализация (или десериализация) будет использовать вместо этих имен свойств.

Итак, для сериализации объявите класс записи и верните его вместо этого.

Также в C # 7 появился новый улучшенный синтаксис для параметров out. Теперь вы можете объявить встроенный out, который лучше подходит в некоторых контекстах:

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

Однако в основном вы будете использовать это в собственных библиотеках .NET, а не в своих собственных функциях.

7 голосов
/ 27 августа 2016

В некоторых из этих ответов указано, что используется параметр out , но я рекомендую не используют это из-за , они не работают с асинхронными методами . Увидеть это для получения дополнительной информации.

Другие ответы приведены с использованием Tuple, который я бы тоже рекомендовал, но с использованием новой функции, представленной в 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}.");

Дополнительную информацию можно найти здесь .

6 голосов
/ 06 марта 2012

вы можете попробовать эту "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);

Выход:

Выход: 1, 2

5 голосов
/ 14 апреля 2009

Классы, структуры, коллекции и массивы могут содержать несколько значений. Выходные и опорные параметры также могут быть установлены в функции. Возврат нескольких значений возможен в динамических и функциональных языках с помощью кортежей, но не в C #.

4 голосов
/ 20 сентября 2013

Вот основные Two методы:

1) Использование 'out' в качестве параметра Вы можете использовать 'out' как для 4.0, так и для минорных версий.

Пример '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();
      }
   }
}

Выход:

Площадь прямоугольника составляет 20

Периметр прямоугольника составляет 18

* Примечание: * Ключевое слово out описывает параметры, чьи фактические местоположения переменных копируются в стек вызываемого метода, где эти же местоположения могут быть переписаны. Это означает, что вызывающий метод получит доступ к измененному параметру.

2) Tuple<T>

Пример кортежа:

Возврат нескольких значений DataType с использованием 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);
    }
    }
}

выход

perl
java
c#
1
2
3

ПРИМЕЧАНИЕ: Использование Tuple действует в Framework 4.0 и более поздних версиях . Tuple - это тип class. Он будет размещен в отдельном месте в управляемой куче в памяти. После создания Tuple вы не сможете изменить значения fields. Это делает Tuple больше похожим на struct.

4 голосов
/ 14 апреля 2009

В основном есть два метода. 1. Используйте параметры out / ref 2. Вернуть массив объектов

3 голосов
/ 11 сентября 2015

Метод, принимающий делегата, может предоставить вызывающей стороне несколько значений. Это заимствовано из моего ответа здесь и использует немного из принятого ответа Хадаса .

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

Вызывающие операторы предоставляют лямбда (или именованную функцию), а подсказки intellisense копируют имена переменных из делегата.

GetMultipleValues((upVotes, comments) =>
{
     Console.WriteLine($"This post has {upVotes} Up Votes and {comments} Comments.");
});
2 голосов
/ 23 ноября 2015

С этой статьей, вы можете использовать три опции, как указано выше.

KeyValuePair - самый быстрый способ.

out на втором.

Кортеж самый медленный.

В любом случае, это зависит от того, что лучше для вашего сценария.

2 голосов
/ 27 мая 2016

Вы можете использовать динамический объект. Я думаю, что он лучше читается, чем 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;
}
2 голосов
/ 18 января 2019
<--Return more statements like this you can --> 

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

Вы можете получить код как

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

Я надеюсь, что это работает.

...