← Назад к вопросам

Что происходит со значением при передачи в параметре метода?

2.0 Middle🔥 111 комментариев
#C# и ООП#Управление памятью

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI7 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Передача параметров в методы C#: значение и ссылка

В C# при передаче параметров в методы происходит одно из двух: передача по значению или передача по ссылке. Поведение зависит от типа параметра (значимый тип или ссылочный) и использования модификаторов ref, out или in.

1. Передача значимых типов по значению (по умолчанию)

Для типов int, float, bool, struct (включая Vector3) и других значимых типов по умолчанию передаётся копия значения. Изменения внутри метода не влияют на исходную переменную.

void ModifyInt(int number)
{
    number = 100; // Работает с копией
}

void Example()
{
    int original = 5;
    ModifyInt(original);
    Debug.Log(original); // Вывод: 5 (значение не изменилось)
}

2. Передача ссылочных типов по значению (по умолчанию)

Для типов class, string, массивы, списки (List<T>) и другие ссылочные типы передаётся копия ссылки на объект в управляемой куче. Сама ссылка копируется, но она указывает на тот же объект.

void ModifyList(List<string> list)
{
    list.Add("New Item"); // Изменяет исходный объект
    list = new List<string>(); // Меняет только локальную копию ссылки
}

void Example()
{
    List<string> myList = new List<string> { "A", "B" };
    ModifyList(myList);
    Debug.Log(string.Join(", ", myList)); // Вывод: A, B, New Item
}

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

3. Передача по ссылке с модификаторами ref, out, in

  • ref – передаёт параметр по ссылке, позволяя методу изменять и значение значимого типа, и саму ссылку для ссылочного типа.
void ModifyWithRef(ref int number)
{
    number = 100; // Изменяет исходную переменную
}
  • out – аналогичен ref, но требует инициализации переменной внутри метода. Полезен для возврата нескольких значений.
bool TryParse(string input, out int result)
{
    return int.TryParse(input, out result);
}
  • in – передаёт параметр по ссылке, но запрещает изменение (только для чтения). Улучшает производительность для больших структур.
float CalculateDistance(in Vector3 point1, in Vector3 point2)
{
    // point1 = Vector3.zero; // Ошибка компиляции
    return Vector3.Distance(point1, point2);
}

Практические последствия для Unity-разработки

  • Структуры Unity (Vector3, Quaternion, Color и т.д.) являются значимыми типами. При передаче в методы создаются копии, что может сказаться на производительности при частых вызовах. В критичных к производительности случаях используйте ref или in.
  • Классы компонентов (Transform, Rigidbody) — ссылочные типы. Передача в методы позволяет модифицировать их состояние.
  • Сценарии MonoBehaviour — всегда ссылочные типы, но их передача в методы редко требуется, так как обычно работа ведётся через поля класса.

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

Понимание этих механизмов критично для написания эффективного, предсказуемого кода и избегания распространённых ошибок, связанных с неожиданным изменением (или неизменением) данных.

Что происходит со значением при передачи в параметре метода? | PrepBro