Как вернуть два значения из метода c

от admin

Как вернуть 2 значения из метода?

Я пробовал с двумя методами, но не получилось вызвать переменные ( вызываются те, что только объявлены, они равны 0 ). Вызывал так :

Могли бы вы, пожалуйста, мне помочь?

  • Вопрос задан более трёх лет назад
  • 3828 просмотров

Простой 1 комментарий

  • Facebook
  • Вконтакте
  • Twitter

GavriKos

Варианты:
1) Обернуть в структуру/класс и возвращать ее инстанс
2) Использовать out/ref
3) Если ссылочный тип — подавать на вход и модифицировать

Как я могу вернуть несколько значений из функции в C #?

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

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

26 ответов

Кортежи с двумя значениями имеют Item1 и Item2 качестве свойств.

Теперь, когда С# 7 выпущен, вы можете использовать новый включенный синтаксис Tuples

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

Вы также можете предоставить имена своим элементам (чтобы они не были «Item1», «Item2» и т.д.). Вы можете сделать это, добавив имя в подпись или методы возврата:

Их также можно деконструировать, что является довольно приятной новой функцией:

Проверьте эту ссылку, чтобы увидеть больше примеров того, что можно сделать 🙂

Вы можете использовать три разных способа

1. параметры ref/out

используя ref:

используя:

2. структура/класс

используя структуру:

используя класс:

3. Кортеж

Класс Tuple

С# 7 кортежей

Вы не можете сделать это на С#. Что вы можете сделать, это иметь параметр out или вернуть свой собственный класс (или структуру, если вы хотите, чтобы он был неизменным).

Использование параметра Использование пользовательского класса (или структуры)

Если вы имеете в виду возврат нескольких значений, вы можете либо вернуть класс /struct, содержащий значения, которые хотите вернуть, либо использовать ключевое слово «out» для своих параметров, например:

Предыдущий плакат прав. Вы не можете вернуть несколько значений из метода С#. Однако у вас есть несколько вариантов:

  • Возвращает структуру, содержащую несколько элементов
  • Возвращает экземпляр класса
  • Используйте выходные параметры (используя ключевые слова out или ref)
  • Используйте словарь или пару ключ-значение в качестве вывода

Достоинства и недостатки здесь часто трудно понять. Если вы вернете структуру, убедитесь, что она маленькая, потому что structs — тип значения и передается в стек. Если вы возвращаете экземпляр класса, здесь есть некоторые шаблоны проектирования, которые вы можете использовать, чтобы избежать возникновения проблем — члены классов могут быть изменены, поскольку С# передает объекты по ссылке (у вас нет ByVal, как вы это делали в VB).

Наконец, вы можете использовать выходные параметры, но я бы ограничил использование этого сценариями, когда у вас есть пара (например, 3 или меньше) параметров — в противном случае все становится уродливо и сложно поддерживать. Кроме того, использование выходных параметров может быть ингибитором гибкости, потому что ваша сигнатура метода должна будет меняться каждый раз, когда вам нужно что-то добавить к возвращаемому значению, а при возврате экземпляра структуры или класса вы можете добавлять элементы без изменения сигнатуры метода.

С архитектурной точки зрения я бы рекомендовал не использовать пары ключ-значение или словари. Я считаю, что этот стиль кодирования требует «секретного знания» в коде, который использует этот метод. Он должен заранее знать, какими будут ключи и что означают значения, и если разработчик, работающий над внутренней реализацией, меняет способ создания словаря или KVP, он может легко создать каскад сбоев во всем приложении.

Возврат нескольких значений из метода в C#

В этом посте будет обсуждаться, как вернуть несколько значений из метода в C#.

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

1. Использование параметров ссылки

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

Методы в C#

Методы в C#, как и практически в любом другом языке программирования — это именованные участки кода, в котором выполняется ряд операций. С методами мы так или иначе сталкивались при изучении возможностей C# с самого начала. Пишем мы первую программу, выводящую на экран строку «Hello world» или изучаем циклы и способы сортировки массивов — мы вызываем в нашей программе хотя бы один метод. И сегодня мы попробуем более детально изучить методы в C#, а также научимся их вызывать.

Определение методов в C#

В самом общем случае, определение метода в C# выглядит следующим образом:

обязательными элементами для определения метода в C# являются: тип возвращаемого значения и имя метода. Самый первый пример метода, который мы могли видеть в C# — это метод Main() , который является и точкой входа для нашего консольного приложения. Рассмотрим описание этого метода:

static — это модификатор. О том, что он обозначает, мы поговорим позднее, когда доберемся до работы с классами и объектами в C#.

void — тип возвращаемого значения. Это ключевое слово используется для того, чтобы указать, что метод не возвращает ничего.

Main — это имя метода.

string[] args — это единственный параметр метода — массив строк.

В фигурных скобках Visual Studio создала нам тело метода, состоящее по умолчанию всего из одной строки — вывод в консоль «Hello world».

Попробуем написать свой первый собственный метод C#. Можно было бы ограничиться стандартными примерами первых методов, типа расчёта площади круга или сложения двух чисел, но мы сделаем по-другому — мы немного улучшим программу сортировки массива, которую написали в прошлый раз.

Учимся определять собственные методы в C#

Посмотрим на исходный код нашей программы:

здесь у нас в методе Main() чего только не напихано — и вывод массива на экран и сортировка выбором. Обычно, участок кода выделяется в отдельный метод, если он (код) повторяется в программе многократно или необходимо выделить решение какой-либо задачи. В нашем же случае в программе можно выделить два отдельных метода:

  1. Метод вывода массива на экран (этот код у нас повторяется дважды — перед сортировкой и после сортировки)
  2. Метод, который будет сортировать массив.

Начнем с метода вывода массива на экран. Название метода должно максимально отражать его суть — пусть название метода будет PrintArray . Далее, что будет возвращать наш метод? В данном случае, ничего возвращать не требуется, поэтому будем использовать void . И, наконец, параметры. Задача метода — вывести на экран массив. Чтобы можно было в дальнейшем многократно использовать наш метод, в качестве параметра метод должен принимать какой-либо массив. Итого, получается вот такое описание метода:

В теле метода мы должны разместить код, который выводит массив на экран, то есть весь метод целиком, включая описание и тело метода у нас должны получиться вот такими:

Здесь мы в цикле foreach перебираем массив, переданный нам в качестве параметра и выводим значения на экран в виде строки.

Второй метод — это метод сортировки массива. Опять же, имя — так как у нас используется сортировка выбором, то пусть метод будет называться SelectSort . Возвращаемое значение также оставляем пустым ( void ), так как перед нами не стоит задачи хранить оба варианта массива (сортированный и несортированный). В качестве параметра будет выступать, опять же массив целых чисел. Весь метод должен выглядеть вот так:

Теперь у нас есть два метода и, если вы все сделали как показано выше, то Visual Studio напишет имена методов серым цветом и предложит удалить неиспользуемые члены класса Program . Выглядит это примерно так:

Читать:
Как играть в штуку

В данном случае, студия права — зачем нам методы, которые нигде не используются? Давайте вызовем наши методы в программе.

Вызов методов C#

Чтобы вызвать метод C# необходимо написать его имя и, при необходимости, в круглых скобках передать методу необходимые параметры. Методы мы будем вызывать внутри метода Main() вот так:

Теперь можно запустить программу и убедиться, что всё работает ровно так, как и в прошлый раз, НО при этом можно назвать следующие преимущества использования методов в C#:

  1. Методы можно многократно использовать в программе (например, PrintArray мы вызвали дважды)
  2. Выделение частей кода в отдельные методы позволяет сделать код более понятным (согласитесь, что изучить код метода на 10-50 строк намного проще, чем изучать «портянку» на 100500 строк)
  3. Использование методов позволяет значительно упростить дальнейшее сопровождение всего проекта. Например, если мы заходим, чтобы значения массива выводились не через пробел, а через запятую, то нам будет достаточно переписать всего один метод, а не искать по всему коду где массив выводится на экран. На небольших проектах это преимущество не совсем очевидно, но, когда вы имеете дело с проектом на десятки и сотни тысяч строк кода, то использование методов становится уже жизненно необходимым (представьте себе программу, хотя бы на 1000 строк кода всего с одним методом…жуть).

Возвращаемые методами C# значения

До сих пор мы имели дело с методами, которые не возвращают значений (с void в качестве возвращаемого значения). Что делать если метод должен вернуть какое-либо значение, например, если мы хотим узнать сколько замен провел наш метод SelectSort , чтобы отсортировать массив по возрастанию? Для этого наш метод должен:

  1. в качестве возвращаемого значения уже иметь не void , а число int (количество перестановок у нас измеряется целыми числами — не может быть 1,5 перестановки)
  2. использовать в теле метода оператор return .

Оператор return завершает выполнение текущего метода и возвращает значение из этого метода. Вызов оператора return выглядит следующим образом:

expression — это значение, которое должен вернуть метод. Если оператор в коде выглядит вот так:

то метод не вернет ничего, но при этом завершит свою работу. Давайте перепишем наш метод SelectSort , чтобы получать не только отсортированный массив, но и количество перестановок, которые были сделаны.

Теперь наша программа сортировки массива станет ещё более информативной. Метод SelectSort можно вызвать вот так:

Здесь мы одной строкой и сортируем массив и выводим в консоль количество перестановок. Результат работы такой программы в консоли будет выглядеть следующим образом:

9 8 7 6 5 4 3 2 1 0

Количество перестановок в массива: 5

0 1 2 3 4 5 6 7 8 9

Методы C#, возвращающие несколько значений

Что, если наш метод должен вернуть не одно, а сразу несколько значений? Опять же,возвращаясь к нашему методу SelectSort — что делать, если нам необходимо вернуть не только количество замен, но и количество сравнений элементов (количество итераций внутреннего цикла for )? Такая задача может решаться несколькими способами, я же покажу лишь один из них — одно значение (количество перестановок) мы будем передавать в качестве возвращаемого значения, а второе — через параметр метода. Сделать это можно, объявив метод следующим образом:

Обратите внимание на то, что написано в круглых скобках после запятой. Ключевое слово out используется для передачи аргументов (параметров) по ссылке. Есть также аналогичное ключевое слово ref , но ref требует, чтобы перед передачей в метод переменная должна была инициализирована, out же этого не требует. Теперь наш метод принимает два параметра один из которых обязательно должен быть переменной. То есть, мы можем вызвать наш метод вот так:

оба параметра — переменные . А можем вот так:

здесь мы передаем в первом параметре значение — массив целых чисел, а во втором переменную (правда, то как будет выглядеть сортированный массив мы уже не увидим). Но вот такой вызов метода уже не пройдет:

Здесь я попытался передать не переменную, а значение и компилятор C# выдал ошибку:

Надеюсь, понятно. Теперь вернемся к нашему методу и перепишем его следующим образом:

Теперь наш метод C# возвращает уже не одно, а два значения: количество перестановок и количество сравнений, а нашу программу можно переписать следующим образом:

Вывод консоли станет ещё более информативным:

9 1 5 6 8 90 -10 13 44 11 54

Количество перестановок в массива: 4. Сравнений 66

-10 1 5 6 8 9 11 13 44 54 90

Как видите, обеспечить возврат нескольких значений одним методом — это не такая уж и проблема. Как я сказал, эту же задачу можно решить несколькими способами, но об этих способах нам пока знать рановато — рассмотрим позднее.

Выход из метода

Выше я уже рассказал, что в методах может использоваться оператор return , который обеспечивает выход из метода и возврат значения метода в вызывающий метод. При этом, оператор return может использоваться и в методах с типом void для прерывания работы метода. Например, следующий код с точки зрения синтаксиса полностью верный:

Но, при этом, строка с вызовом WriteLine абсолютно бесполезна так как до этой строки мы никогда не дойдем — оператор return заставит нас выйти из метода сразу же, не достигая конца тела метода. Поэтому на будущее стоит запомнить,что return необходимо располагать именно в том месте где действительно необходимо обеспечить выход из метода, например, перед последней фигурной скобкой.

Сокращенная запись методов в C#

Если тело метода содержит всего одну инструкцию, то допускается сокращенная запись такого метода. Например, пусть у нас есть такой метод:

тело метода содержит всего одну инструкцию — вывод сообщения в консоль. В этом случае, мы можем сократить наш метод до следующей записи:

то есть, вместо фигурных скобок мы используем оператор => и далее сразу пишем содержимое тела метода (единственную инструкцию).

В чем различие между методом, функцией и процедурой

В различных источниках информации, кроме названия «метод» можно встретить также и такие названия как «функция» и «процедура». В чем же принципиальное отличие метода, функции и процедуры? Применительно к C#, в отличие, например, от Delphi/Pascal — это, скорее, философский вопрос. На мой взгляд, в C# все эти три понятия тождественны.

Обычно, функцию определяют так: функция — это метод, который возвращает какое-либо значение. Например, наш метод SelectSort возвращает значение int . То есть, технически мы можем сказать, что SelectSort — это функция.

В свою очередь, процедура — это метод, который не возвращает ничего. Опять же, чисто технически, можно сказать, что наш метод PrintArray — это процедура. Но, если обратить внимание на справочник по C#, то там « void — указывает тип возвращаемого значения для метода, который не возвращает значения.» Вот такая вот философская задача. То есть вроде как и нет возвращаемого значения, но всё же тип возвращаемого значения — void.

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

Итого

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

Похожие статьи