Есть ли способ, которым я могу вернуть более одного целого числа из метода? - программирование

Есть ли способ, которым я могу вернуть более одного целого числа из метода?

У меня есть такой метод:

private double GetHeight()
{
    return 2;
}

Но я хотел бы иметь возможность вернуть два разных числа для примера 2 и 3. Есть ли способ, которым я могу сделать это в С#?

4b9b3361

Ответ 1

Да ValueTuple/Named Tuple (доступно в С# 7.1). Преимущество в том, что он самый лаконичный, неизменный и его легко построить.

Структура ValueTuple имеет поля с именами Item1, Item2, Item3 и т.д., Аналогичные свойствам, определенным в существующих типах Tuple.

Однако, когда вы инициализируете кортеж, вы можете использовать новые языковые функции, которые дают лучшие имена для каждого поля. Это создает именованный кортеж. Именованные кортежи все еще имеют элементы с именами Item1, Item2, Item3 и так далее. Но у них также есть синонимы для любого из тех элементов, которые вы назвали. Вы создаете именованный кортеж, указывая имена для каждого элемента.

private (double first, double second) GetHeight()
{
   return (1,2);
}

...

var result = ViaNamedValueTuple();
Console.WriteLine($"{result.first}, {result.second}");

var (first, second) = ViaNamedValueTuple();
Console.WriteLine($"{first}, {second}");

Классический кортеж

Тип кортежа С#

.NET Framework уже имеет универсальные классы Tuple. Эти классы, однако, имели два основных ограничения. Например, классы Tuple назвали свои свойства Item1, Item2 и т.д. Эти имена не несут смысловой информации. Использование этих типов кортежей не позволяет передать значение каждого из свойств. Новые возможности языка позволяют вам объявлять и использовать семантически значимые имена для элементов в кортеже.

public Tuple<int, int> ViaClassicTuple()
{
   return new Tuple<int, int>(1,2);
}

...

var tuple = ViaClassicTuple();
Console.WriteLine($"{tuple.Item1}, {tuple.Item2}");

Классическая структура

struct (С# Reference)

Тип структуры - это тип значения, который обычно используется для инкапсуляции небольших групп связанных переменных, таких как координаты прямоугольника или характеристики предмета в инвентаре.

public struct ClassicStruct
{
   public int First { get; set; }
   public int Second { get; set; }
   public ClassicStruct(int first, int second)
   {
      First = first;
      Second = second;
   }
}

...

public ClassicStruct ViaClassicStruct()
{
   return new ClassicStruct(1, 2);
}

... 

var classicStruct = ViaClassicStruct();
Console.WriteLine($"{classicStruct.First}, {classicStruct.Second}");

Только для чтения

только для чтения (С# Reference)

Модификатор readonly в определении структуры объявляет, что структура неизменна. Каждое поле экземпляра структуры должно быть помечено только для чтения, как показано в следующем примере:

public readonly struct ReadonlyStruct
{
   public int First { get; }
   public int Second { get; }
   public ReadonlyStruct(int first, int second)
   {
      First = first;
      Second = second;
   }
}

...

public ReadonlyStruct ViaReadonlyStruct()
{
   return new ReadonlyStruct(1, 2);
}

...


var readonlyStruct = ViaReadonlyStruct();
Console.WriteLine($"{readonlyStruct.First}, {readonlyStruct.Second}");

Простой класс

Классы (Руководство по программированию в С#)

Тип, определенный как класс, является ссылочным типом. Во время выполнения, когда вы объявляете переменную ссылочного типа, переменная содержит значение null, пока вы явно не создадите экземпляр класса с помощью оператора new или не назначите ему объект совместимого типа, который, возможно, был создан в другом месте.

public class SomeClass
{
   public int First { get; set; }
   public int Second { get; set; }
   public SomeClass(int first, int second)
   {
      First = first;
      Second = second;
   }
}

...

public SomeClass ViaSomeClass()
{
   return new SomeClass(1, 2);
}

...


var someClass = ViaSomeClass();
Console.WriteLine($"{someClass.First}, {someClass.Second}");

Выходные параметры

модификатор параметра out (С# Reference)

Ключевое слово out вызывает передачу аргументов по ссылке. Это делает формальный параметр псевдонимом для аргумента, который должен быть переменной. Другими словами, любая операция над параметром производится над аргументом. Это похоже на ключевое слово ref, за исключением того, что ref требует инициализации переменной перед ее передачей. Это также похоже на ключевое слово in, за исключением того, что in не позволяет вызываемому методу изменять значение аргумента. Чтобы использовать параметр out, и определение метода, и вызывающий метод должны явно использовать ключевое слово out.

public bool ViaOutParams(out int first, out int second)
{
   first = 1;
   second = 2;
   return someCondition;
}

...

if(ViaOutParams(out var firstInt, out var secondInt))
   Console.WriteLine($"{firstInt}, {secondInt}");

Выходная стоимость Tuple

public bool ViaOutTuple(out (int first,int second) output)
{
   output = (1, 2);
   return someCondition;
}

...

if (ViaOutTuple(out var output))
   Console.WriteLine($"{output.first}, {output.second}");

Ответ 2

Несколько способов:

  1. out параметры:

    private double GetHeight(out int anotherValue)
    {
        anotherValue = 42;
        return 2;
    }
    
  2. значение кортежи:

    private (double height, int anotherValue) GetHeight()
    {
        return (42, 2);
    }
    

    (предупреждение: у кортежей-значений есть известные проблемы, если они используются в библиотеках .NET Standard, поскольку привязки сборок из .NET Standard к .NET Framework являются... своего рода fubar)

  3. пользовательские типы возврата:

    private Something GetHeight()
    {
        return new Something(42, 2);
    }
    

    (во избежание выделения в этом сценарии вы можете определить Something как readonly struct для readonly struct)

Ответ 3

Да, вы можете использовать Tuple:

class Program
  {
    static void Main(string[] args)
    {
      Tuple<int, int> height = GetHeight();

      Console.WriteLine(height.Item1 + " - " + height.Item2);
      Console.ReadLine();
    }

    private static Tuple<int, int> GetHeight()
    {
      return new Tuple<int, int>(2, 3);
    }
  }

ВЫХОД:

2 - 3

Ответ 4

Также вы можете использовать out параметров:

static void Main(string[] args)
{
  int i, j;
  GetHeight(out i, out j);
}

public static void GetHeight(out int i1, out int i2)
{
  i1 = 1;
  i2 = 2;
}

Ответ 5

Создайте массив int. Или другой способ - создать класс.