Поддерживает ли С# несколько возвращаемых значений?
Это очень простой вопрос, и если то, что я собираюсь сделать, сложно/вовлечено, то я не ожидаю, что вы вникнете в подробности... Я читал, что это может включать в себя структуры или хэш или некоторые Другая страшная процедура, к которой я еще не пришел. Если это так, я уверен, что это скоро меня доставит.
Работа над учебными классами, методами и возвращаемыми значениями.
Я хочу, чтобы мой класс/метод возвращал текущий час и минуту. На самом деле достаточно просто.
Правильно ли это построено или правильно?
class MyClass
{
public int GetHour (int hr, int min)
{
DateTime dt = DateTime.Now;
int hour = dt.Hour;
int minute = dt.Minute;
return hour;
return minute;
}
}
И, называя его от Main()
: Получение некоторых ошибок (No overload for method
и Unreachable code detected
)
static void Main ( string[] args )
{
MyClass mc = new MyClass ();
Console.WriteLine ("Hour: {0} \n Minute: {1}", mc.GetHour());
Console.ReadLine ();
}
Вопрос: я закрыл?
Ответы
Ответ 1
Как упоминалось @ChaosPandion, в этом конкретном случае вы вернете структуру DateTime
.
В общем, однако, у вас есть следующие опции:
Использование параметров out
Это простой способ, который обычно всегда работает. Однако это немного неуклюже, так как результат возвращается туда, где обычно вы ожидаете, что аргументы функции будут переданы, и подпись метода может стать длинной и сложной для рефакторинга.
public void GetTime(out int hr, out int min)
{
DateTime dt = DateTime.Now;
hr = dt.Hour;
min = dt.Minute;
}
static void Main(string[] args)
{
// declare variables for out parameters first
int hour, minute;
GetTime(out hour, out minute);
}
Использование массива
Это простой метод, который хорошо работает, если возвращаемые значения имеют один и тот же тип.
public int[] GetTime()
{
DateTime dt = DateTime.Now;
return new[] { dt.Hour, dt.Minute};
}
Использование пакета свойств (мешок свойств - это простой класс, который имеет только свойства)
Это очень удобно и позволяет легко модифицировать тип и количество возвращаемых значений позже без изменения сигнатуры метода.
class A
{
int Prop1 { get; set; }
int Prop2 { get; set; }
}
public A SomeMethod()
{
return new A() { Prop1 = 1, Prop2 = 2 }
}
Использование кортежа
В С# 4.0 (требуется VS 2010) вы можете использовать класс Tuple<T1, T2, ...>
:
public Tuple<int, int> GetTime()
{
DateTime dt = DateTime.Now;
return Tuple.Create(dt.Hour, dt.Minute);
}
С# 7.0 Кортежи
С# 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
}
Элементы кортежа по умолчанию являются именами Item1
, Item2
и т.д., но вы также можете указать имена, например.
(string first, string middle, string last) 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.first} {names.last}.");
Ответ 2
С# не поддерживает несколько возвращаемых значений, поэтому в этом случае вы должны вернуть структуру DateTime
, которая является идиоматическим подходом. Клиентский код может просто игнорировать свойства, которые им не нужны. Вы можете создать свою собственную простую структуру, но это действительно не стоит усилий.
Ответ 3
С# не поддерживает идею прямого возвращения нескольких значений из метода таким образом. Однако существует несколько способов создания методов, которые возвращают несколько значений. Во-первых, используйте параметры ref
/out
.
public void GetHourMinute(out int hour, out int minute) {
var now = DateTime.Now;
hour = now.Hour;
minute = now.Minute;
}
Второй способ - создать тип оболочки, который инкапсулирует два значения. Начиная с версии 4.0 это можно сделать немного проще, используя тип Tuple
.
public Tuple<int,int> GetHourMinute() {
var now = DateTime.Now;
return Tuple.Create(now.Hour, now.Minute);
}
Ответ 4
1: Вы не можете иметь два return
s. Как только компилятор достигает инструкции return
, операция метода завершена.
2: Почему вы хотите, чтобы ваш метод получал параметры, если вы их не используете? DateTime.Now
дает текущее время , если вы думаете о себе как о том, что вам нужно для выполнения вашей задачи? Ничего.
Итак, практические советы:
1. Фактически, DateTime делает то, что вам нужно, лучше, чем ваш метод.
Console.WriteLine ("Hour: {0} \n Minute: {1}", DateTime.Now.Hour,DateTime.Now.Minute);
Было бы лучше,
но игнорировать это и рассматривать это упражнение в классах.
2 Возвращение двух значений противоречит понятию метода - метод возвращает одну вещь (есть исключения как out
ref
, но мы их проигнорируем).
Фактически вы можете видеть, что в вашем собственном коде - ваше имя метода GetHour
not GetHourAndMinutes
. Я не думаю, что когда-либо видел имя метода со словом "и" - метод делает только одно.
Ответ 5
Я предлагаю вам вернуть объект DateTime. Затем в основном методе вы вызываете свойства Hour и Minute.
Ответ 6
Да, вы можете вернуть только одну вещь из метода на С#.
Другая проблема заключается в том, что вы вызываете метод без каких-либо параметров. Вещи в скобках:
public int GetHour (int hr, int min) // here
{
}
Являются ли параметры. И вам нужно указать их при вызове метода, например:
mc.GetHour(1, 2);
Но, конечно, в вашем случае это не имеет смысла делать.
Чтобы ответить на общий вопрос: "Как мне вернуть больше одного?" Вы инкапсулируете его в класс, задаете свойства и возвращаете этот класс. Так получилось, что в приведенном примере класс DateTime делает именно это.
Надеюсь, что это будет полезно.
Ответ 7
Извините, вы не можете этого сделать. Вам лучше будет возвращать массив или объект. Вы можете вернуть объект DateTime и использовать его.
Также, как указано, ваша подпись функции не вызывалась должным образом.
class MyClass
{
public int[] GetHour ()
{
DateTime dt = DateTime.Now;
int hour = dt.Hour;
int minute = dt.Minute;
return new int[]{hour, minute};
}
}
static void Main ( string[] args )
{
MyClass mc = new MyClass ();
int[] temp = mc.GetHour();
Console.WriteLine ("Hour: {0} \n Minute: {1}", temp[0], temp[1]);
Console.ReadLine ();
}
Ответ 8
Вы не можете вернуть несколько значений. TimeSpan - именно то, что вы ищете. Создайте объект с часами, минутами и даже секундами, которые вы хотите захватить и вернуть.
Подумайте об этом, для чего вам нужно выше, вам даже не нужно писать метод выше. Просто используйте DateTime.Now.TimeOfDay
непосредственно в своем коде
Ответ 9
Вы не можете вернуться дважды, только один раз.
Несколько возвращаемых значений сразу требуют лямбда-выражений и AFAIK, только Python способен на это.
Синтаксис выглядит следующим образом:
return x, y
Так что, возможно, вам стоит попробовать IronPython, а затем декомпилировать С#.
В С# существует ровно два способа вернуть более одного значения:
1. Используйте аргументы как вызов по ссылке, таким образом вы можете назначить 3 переменные, а затем вернуться.
2. Используйте какой-то тип struct/class/array/tuple/vector и поместите в него несколько значений.
Вызов по ссылке выглядит примерно так:
public static void xxx (ref var1, ref var2, ref var3) { var1 = 123; var2 = 456; var3 = 789; вернуть; }
тогда вы выполните:
int a =1;
int b=2;
int c=3;
xxx(ref a, ref b, ref c);
Console.WriteLine(a.ToString());
Console.WriteLine(b.ToString());
Console.WriteLine(c.ToString());
Ответ 10
В С# метод может возвращаться несколько раз, если вы используете формат yield return
.
using System.Collections.Generic;
namespace YieldReturn
{
class Program
{
public static void Main(string[] args)
{
MyClass mc = new MyClass();
IEnumerator<int> enu = mc.GetHour().GetEnumerator();
enu.MoveNext();
int hour = enu.Current;
enu.MoveNext();
int min = enu.Current;
Console.WriteLine("Hour {0} min {1}", hour, min);
Console.ReadKey(true);
}
}
class MyClass
{
DateTime dt;
public MyClass()
{
dt = DateTime.Now;
}
public IEnumerable<int> GetHour()
{
int hour = dt.Hour;
int minute = dt.Minute;
yield return hour;
yield return minute;
}
}
}
Дает "Час 8 мин 50"
Ответ 11
Вопрос, который я хотел бы задать вам, - это почему вы хотите вернуть несколько значений? Возвращение нескольких значений для меня означает наличие нескольких функций в функции, и это должно быть большим, поскольку это нарушает SRP. Но, если эти возвращаемые значения связаны, возможно, они создают объект, который вам не хватает, и его следует создать вместо этого? Или список с одним типом объекта.
Итак, коротко. Зачем? Инкапсулировать возвращаемые значения в ОДНОМ объекте? Не выполняйте несколько действий в одной функции.
РЕДАКТИРОВАТЬ: В вашем случае я бы даже не включил вашу функциональность только в функцию:
static void Main ( string[] args )
{
MyClass mc = new MyClass ();
DateTime now = DateTime.Now;
int hour = now.Hour;
int min = now.Minute;
Console.WriteLine ("Hour: {0} \n Minute: {1}", hour, min);
Console.ReadLine ();
}
И ваше имя функции GetHour
не выполняет то, что говорит функция... если он говорит GetHour
, он должен вернуть час и не час плюс минута.