
В C# массивы являются ссылочными типами данных, что напрямую влияет на способы их передачи в функции. При стандартной передаче массива в метод фактически передается ссылка на объект массива, а не его копия. Это позволяет изменять содержимое массива внутри функции без создания нового массива, что важно учитывать при проектировании алгоритмов.
Для передачи массива можно использовать ключевые слова ref и out. ref позволяет методу изменять саму ссылку на массив, например, заменять массив на новый, тогда как out гарантирует, что массив будет инициализирован внутри функции перед использованием. Применение этих ключевых слов требует явного указания в сигнатуре метода и при вызове.
Кроме этого, для функций, которым нужно работать с неизменяемыми данными массива, эффективным решением является передача копии массива с помощью метода Array.Copy или Clone(). Такой подход предотвращает непреднамеренные изменения исходных данных, сохраняя целостность информации при многократных вызовах методов.
В C# также допустимо использовать массивы в сочетании с параметром params, что позволяет передавать произвольное количество элементов без предварительного создания массива. Это упрощает вызовы метода и делает код более компактным, особенно при обработке списков чисел или строк.
Передача массива в функцию на C#: примеры и способы

В C# массивы можно передавать в функции несколькими способами, каждый из которых имеет свои особенности и цели. Основные варианты – передача по значению, по ссылке и использование ключевого слова params.
1. Передача массива по значению
При передаче массива как аргумента по умолчанию передаётся ссылка на сам массив, поэтому изменения элементов внутри функции отражаются на исходном массиве.
void ModifyArray(int[] arr) {
arr[0] = 100;
}
int[] numbers = {1, 2, 3};
ModifyArray(numbers);
// numbers[0] теперь равен 100
Важно: при этом нельзя изменить саму ссылку на массив и ожидать, что она обновится вне функции.
2. Передача массива по ссылке с ref
Использование ref позволяет функции переназначить массив целиком, создавая новый объект.
void ReplaceArray(ref int[] arr) {
arr = new int[] {10, 20, 30};
}
int[] numbers = {1, 2, 3};
ReplaceArray(ref numbers);
// numbers теперь содержит {10, 20, 30}
3. Передача массива с out
Ключевое слово out позволяет функции инициализировать массив, не требуя предварительного создания объекта перед вызовом.
void InitializeArray(out int[] arr) {
arr = new int[3] {5, 10, 15};
}
int[] numbers;
InitializeArray(out numbers);
// numbers теперь содержит {5, 10, 15}
4. Использование params для передачи произвольного числа элементов
![4. Использование undefinedparams</code> для передачи произвольного числа элементов»></p>
<p>Ключевое слово <code>params</code> позволяет передавать любое количество значений без явного создания массива.</p>
<pre><code>void PrintNumbers(params int[] nums) {
foreach (var n in nums) {
Console.WriteLine(n);
}
}
PrintNumbers(1, 2, 3, 4);
</code></pre>
<h3>5. Рекомендации</h3>
<p><img decoding=](/wp-content/images8/kak-peredat-massiv-v-funktsiyu-si-sharp-9kyaopgw.jpg)
- Для изменения элементов массива используйте стандартную передачу по значению.
- Для создания нового массива внутри функции применяйте
refилиout. paramsудобен для функций с переменным числом аргументов.- Следите за производительностью: копирование больших массивов через
refили возврат нового массива создаёт дополнительную нагрузку на память.
Как передавать массив по значению и что это означает
Чтобы передать массив по значению, необходимо создать его полную копию. Для одномерного массива можно использовать метод Array.Copy или метод расширения Clone(). Например:
int[] original = {1, 2, 3};
int[] copy = (int[])original.Clone();
После передачи copy в функцию любые изменения не повлияют на original. Это особенно важно, когда требуется исключить побочные эффекты или сохранить исходные данные без изменения.
Для многомерных массивов метод Clone() создаёт поверхностную копию, поэтому вложенные массивы остаются ссылками на оригинальные объекты. В таких случаях нужно реализовать глубокое копирование вручную, например через цикл перебора элементов и создание новых вложенных массивов.
Рекомендация: если массив небольшой и требуется защита от модификаций в функции, используйте Clone(). Для больших массивов создание копии может быть затратным, поэтому альтернативой может быть ReadOnlySpan или передача массива как ReadOnlyMemory для безопасного чтения без копирования.
Таким образом, передача массива по значению в C# фактически требует явного создания копии, а понимание этого позволяет контролировать изменение данных и управлять производительностью программы.
Использование ключевого слова ref для изменения массива внутри функции
В C# массивы передаются в функции по ссылке по умолчанию, однако ключевое слово ref позволяет не только изменять элементы массива, но и переназначать сам массив на новый объект. Это полезно, когда требуется заменить исходный массив на другой внутри метода.
Пример использования ref для изменения массива:
void ИзменитьМассив(ref int[] arr)
{
// Переназначаем массив на новый
arr = new int[] { 10, 20, 30 };
}
int[] массив = { 1, 2, 3 };
ИзменитьМассив(ref массив);
// массив теперь содержит {10, 20, 30}
Важно учитывать, что без ref переназначение массива внутри функции не влияет на исходный объект. Использование ref гарантирует прямое воздействие на переданную переменную.
Пример модификации элементов существующего массива с ref:
void УвеличитьЭлементы(ref int[] arr)
{
for (int i = 0; i < arr.Length; i++)
{
arr[i] += 5;
}
}
int[] массив = { 1, 2, 3 };
УвеличитьЭлементы(ref массив);
// массив теперь содержит {6, 7, 8}
Рекомендации при использовании ref с массивами:
| Ситуация | Рекомендация |
|---|---|
| Необходимость изменить размер массива | Использовать ref, чтобы переназначить новый массив |
| Только модификация элементов | Можно обойтись без ref, достаточно работать с элементами напрямую |
| Повторное использование переменной массива | Передавать с ref, чтобы изменения сохранялись вне функции |
| Оптимизация памяти | Использовать ref только при необходимости переназначения, иначе создаются лишние объекты |
Использование ref повышает контроль над массивом и позволяет изменять его структуру и элементы в вызывающем коде без дополнительных возвратов значений.
Передача массива с помощью out для возврата данных из функции

В C# ключевое слово out позволяет функции возвращать массив без необходимости создавать его заранее. Массив, переданный через out, инициализируется внутри метода, и вызывающий код получает ссылку на новый объект.
Пример использования:
Код:
void СоздатьМассив(out int[] массив, int размер)
{
массив = new int[размер];
for (int i = 0; i < размер; i++)
массив[i] = i * 2;
}
Вызов функции:
int[] результат;
СоздатьМассив(out результат, 5);
foreach (var элемент in результат)
Console.WriteLine(элемент);
Результат выполнения кода будет: 0, 2, 4, 6, 8. Такой подход исключает необходимость заранее выделять память под массив, что особенно удобно при динамическом формировании данных внутри метода.
При использовании out важно помнить: массив внутри функции должен быть обязательно инициализирован до выхода из метода. Любая попытка вернуть out без присвоения вызовет ошибку компиляции.
Рекомендуется использовать out для массивов, когда размер или содержимое заранее неизвестны, а функция формирует полный набор данных. Это повышает читаемость кода и уменьшает риск ошибок при работе с пустыми или частично заполненными массивами.
Передача массива как параметра метода с параметром params
В C# ключевое слово params позволяет передавать в метод переменное количество аргументов одного типа, включая массив. Метод, объявленный с params, автоматически принимает как отдельные элементы, так и массив.
Синтаксис объявления метода с params выглядит так: void MethodName(params int[] numbers). Здесь numbers можно передавать как отдельные значения MethodName(1, 2, 3), так и массив int[] arr = {1,2,3}; MethodName(arr).
Важно учитывать, что параметр params должен быть последним в списке параметров метода. Любые другие параметры должны располагаться перед ним.
Использование params удобно для методов суммирования, объединения строк или передачи коллекций неизвестной длины. Например, метод для суммирования чисел:
int Sum(params int[] values) { int total = 0; foreach(var v in values) total += v; return total; }. Его можно вызвать как Sum(5, 10, 15) или Sum(new int[]{5,10,15}).
Применение params уменьшает необходимость перегрузки методов и упрощает работу с массивами и списками фиксированной или динамической длины.
При передаче массивов через params избегайте многократного создания временных массивов внутри цикла – это снижает производительность. Если количество элементов заранее известно, лучше напрямую передавать массив без params.
Для ссылочных типов params передает ссылку на массив, изменения внутри метода отражаются на исходном массиве. Для значимых типов происходит копирование элементов в новый массив при вызове с перечислением отдельных значений.
Копирование массива перед передачей в функцию
В C# массивы передаются в функции по ссылке, поэтому любые изменения внутри функции затрагивают исходный массив. Чтобы избежать этого, используется копирование массива перед передачей. Существует несколько методов копирования.
Метод Array.Copy позволяет создать новый массив с заданной длиной и скопировать элементы:
int[] original = {1, 2, 3, 4};
int[] copy = new int[original.Length];
Array.Copy(original, copy, original.Length);
ProcessArray(copy);
Метод Clone() создаёт поверхностную копию массива. Для одномерных массивов типов значений этого достаточно:
int[] copy = (int[])original.Clone();
ProcessArray(copy);
Для массивов ссылочных типов или многомерных массивов лучше использовать LINQ или ручное копирование элементов, чтобы избежать изменения вложенных объектов:
var copy = original.Select(x => x).ToArray();
ProcessArray(copy);
Пример сравнения исходного массива и его копии после передачи в функцию:
| Массив | До функции | После функции |
|---|---|---|
| original | {1, 2, 3, 4} | {1, 2, 3, 4} |
| copy | {1, 2, 3, 4} | {10, 20, 30, 40} |
Рекомендация: для безопасной передачи массивов в функции, которые могут их изменять, используйте копирование через Clone() или Array.Copy. Для сложных структур используйте глубокое копирование с перебором элементов.
Передача многомерных массивов в функции C#
Простейший пример передачи двумерного массива в функцию:
void PrintMatrix(int[,] matrix)
{
for (int i = 0; i < matrix.GetLength(0); i++)
{
for (int j = 0; j < matrix.GetLength(1); j++)
{
Console.Write(matrix[i, j] + " ");
}
Console.WriteLine();
}
}
int[,] myMatrix = { {1, 2}, {3, 4} };
PrintMatrix(myMatrix);
Ключевые моменты:
- Использовать
GetLength(dimension)для определения размера каждой оси. - Изменения элементов массива внутри функции отражаются на исходном массиве.
- Передача по ссылке через ключевое слово
refнеобходима только если требуется переназначить сам массив.
Пример передачи массива с возможностью переназначения:
void ReplaceMatrix(ref int[,] matrix)
{
matrix = new int[2, 2] { {5, 6}, {7, 8} };
}
int[,] original = { {1, 2}, {3, 4} };
ReplaceMatrix(ref original);
Для трехмерных и более сложных массивов принцип передачи сохраняется. Рекомендуется:
- Явно указывать количество измерений при создании массива.
- Использовать вложенные циклы
forдля обхода всех измерений. - Для больших массивов рассматривать использование
Span<T>илиMemory<T>для оптимизации работы с памятью.
Передача многомерного массива в функцию позволяет централизованно обрабатывать данные, избегая дублирования кода, но требует аккуратного управления индексами и понимания, что массив передается по ссылке.
Передача массивов объектов и работа с ссылками
В C# массив объектов представляет собой массив ссылок на экземпляры классов. При передаче такого массива в функцию передается копия ссылок, а не сам объект. Изменения полей объектов внутри функции сохраняются после выхода из нее, тогда как изменение самой ссылки на объект внутри функции не повлияет на исходный массив.
Пример передачи массива объектов:
class Person
{
public string Name;
public int Age;
}
void UpdateAges(Person[] people)
{
foreach (var person in people)
{
person.Age += 1;
}
}
Person[] group = {
new Person { Name = "Анна", Age = 25 },
new Person { Name = "Борис", Age = 30 }
};
UpdateAges(group);
// Возраст всех объектов увеличен на 1
Если требуется заменить объекты внутри массива, можно использовать модификацию по индексу:
void ReplaceFirst(Person[] people)
{
people[0] = new Person { Name = "Виктор", Age = 40 };
}
ReplaceFirst(group);
// Первый элемент массива теперь указывает на новый объект
Рекомендации при работе с массивами объектов:
- Использовать foreach для изменения свойств объектов, а не самой ссылки.
- Для полной замены объектов применять доступ по индексу или метод ref.
- При передаче массива в методы, если требуется возможность заменить весь массив, использовать ключевое слово
refили возвращать новый массив. - Избегать глубоких копий объектов, если изменения должны распространяться на оригинальные элементы.
Пример использования ref для замены массива целиком:
void ReplaceArray(ref Person[] people)
{
people = new Person[] {
new Person { Name = "Георгий", Age = 50 }
};
}
ReplaceArray(ref group);
// group теперь содержит новый массив с одним элементом
Примеры вызова функций с массивами разных типов
В C# массивы можно передавать в функции по ссылке или по значению, в зависимости от того, требуется ли изменение исходного массива. Рассмотрим примеры для разных типов данных.
Массив целых чисел:
int[] numbers = {1, 2, 3, 4, 5};
void PrintSum(int[] arr) { int sum = 0; foreach(var n in arr) sum += n; Console.WriteLine(sum); }
Массив строк:
string[] names = {"Анна", "Борис", "Светлана"};
void PrintNames(string[] arr) { foreach(var name in arr) Console.WriteLine(name); }
Массив объектов:
Person[] people = { new Person("Иван"), new Person("Мария") };
void ShowPeople(Person[] arr) { foreach(var p in arr) Console.WriteLine(p.Name); }
ShowPeople(people); – функция демонстрирует работу с массивами пользовательских классов.
Массив булевых значений:
bool[] flags = { true, false, true };
void InvertFlags(bool[] arr) { for(int i=0;i
InvertFlags(flags); – функция изменяет исходный массив, демонстрируя передачу по ссылке.
Рекомендации: передавая массивы, учитывайте их размер и тип, избегайте избыточного копирования при больших данных, используйте ref или out только при необходимости изменения ссылки на массив.
Вопрос-ответ:
Как передать массив в функцию по значению и по ссылке в C#?
В C# массивы по умолчанию передаются в функции по ссылке на объект, хотя синтаксис может выглядеть как передача по значению. Если нужно передать массив полностью, так чтобы изменения внутри функции не влияли на оригинал, можно создать копию массива и передать её. Для явной передачи по ссылке используется ключевое слово ref, тогда изменения самой переменной массива будут видны снаружи функции.
Можно ли передавать в функцию массивы разной длины?
Да, C# позволяет передавать массивы любых размеров. Для этого в объявлении функции указывается тип массива, например int[] arr, без указания размера. Также можно использовать параметр params, если требуется передавать произвольное количество элементов, которые будут автоматически собраны в массив.
Что произойдёт, если внутри функции изменить элементы переданного массива?
Если массив передан в функцию обычным образом, изменения элементов будут видны за пределами функции, потому что массив передаётся как ссылка на объект. Например, изменение arr[0] = 10 внутри функции изменит первый элемент исходного массива. Если нужно избежать таких изменений, следует передавать копию массива или использовать методы типа Array.Copy.
Как правильно передать многомерный массив в функцию?
Многомерные массивы в C# можно передавать в функции аналогично одномерным. Например, для двумерного массива int[,] matrix в параметрах функции указывается его тип. Изменения элементов внутри функции будут отражены на оригинальном массиве, так как передаётся ссылка на объект. Если требуется передавать массив как неизменяемый, нужно создать его копию.
В чём разница между ref и out при передаче массива в функцию?
Ключевое слово ref позволяет передавать массив так, чтобы функция могла изменить сам объект или ссылку на него, при этом массив должен быть инициализирован до вызова функции. out используется для передачи массива, который будет создан или присвоен внутри функции; переменная не обязана быть инициализирована до вызова, но функция обязана присвоить ей значение перед завершением.
