Back to Blog
C#

C# Pass Array to Method: Syntax and Behavior

c# pass array to method: Learn how C# passes arrays to methods as references, including params, ref, and ReadOnlySpan for read-only access.

C# ArraysMethod Parametersparams KeywordReadOnlySpanReference Types
Illustration of a C# method receiving an array reference, showing that the caller and method share the same array object.

When you pass an array to a method in C#, the method receives a reference to the same array instance, not a copy of its contents. Arrays are reference types, so any change made to an element inside the method is visible to the caller after the method returns. This is the core behavior behind c# pass array to method and it affects how you design method signatures, how you guard against unintended mutation, and which parameter types you choose.

How Array Parameters Work in C#

In C#, an array is a reference type. When you declare int[] numbers = new int[5];, the variable numbers holds a reference to the array object on the managed heap. Passing that variable to a method copies the reference, not the array data. Both the caller and the method point to the same underlying object.

public static void DoubleFirstElement(int[] values) { values[0] *= 2; } int[] data = { 1, 2, 3 }; DoubleFirstElement(data); Console.WriteLine(data[0]); // 2

The method does not need to return the modified array because the change happens on the same object. Returning the array is only necessary when the method creates a new array instance.

Declaring a Method That Accepts an Array

The syntax for an array parameter is straightforward: you specify the element type followed by square brackets.

public static int Sum(int[] values) { int total = 0; foreach (int value in values) { total += value; } return total; }

You can call this method with any array whose element type matches, including arrays created inline:

int result = Sum(new int[] { 4, 5, 6 });

The parameter is a reference, so passing a large array does not copy its elements. The cost of the call is fixed regardless of array size, which is why passing arrays is generally cheap compared to copying collections.

Using the params Keyword for Variable-Length Arguments

When you want a method to accept a variable number of arguments without requiring the caller to construct an array explicitly, use the params keyword. The compiler collects the arguments into an array behind the scenes.

public static int SumAll(params int[] values) { int total = 0; foreach (int value in values) { total += value; } return total; }

The method can be called with individual arguments or with an array:

int a = SumAll(1, 2, 3); int b = SumAll(10, 20); int c = SumAll(new int[] { 7, 8 });

The params parameter must be the last parameter in the signature, and there can be only one. This is a convenience for callers, but the method still receives an array reference, so the same mutation rules apply.

Reassigning the Array Reference with ref

Passing an array without ref means the method can modify elements, but it cannot replace the caller's array variable. If the method assigns a new array to the parameter, the caller's variable still points to the original array.

public static void TryReplace(int[] values) { values = new int[] { 9, 9, 9 }; } int[] data = { 1, 2, 3 }; TryReplace(data); Console.WriteLine(data[0]); // 1

To allow the method to replace the array entirely, pass it with the ref keyword. The parameter then becomes an alias for the caller's variable.

public static void ReplaceWithLarger(int[] values, int newSize) { int[] larger = new int[newSize]; Array.Copy(values, larger, values.Length); values = larger; } int[] data = { 1, 2, 3 }; ReplaceWithLarger(ref data, 10); Console.WriteLine(data.Length); // 10

Using ref signals that the method may change which array the caller's variable points to. Reserve it for cases where reassignment is actually required, because it makes the method's side effects harder to predict.

Read-Only Array Access with ReadOnlySpan<T>

If a method only needs to read array data, ReadOnlySpan<T> provides a view over the array without copying and without allowing modification. This is useful for performance-sensitive code where you want to communicate intent clearly.

public static int SumSpan(ReadOnlySpan<int> values) { int total = 0; foreach (int value in values) { total += value; } return total; } int[] data = { 1, 2, 3 }; int result = SumSpan(data);

The array is implicitly converted to a ReadOnlySpan<int>. The method cannot modify elements through the span, which prevents accidental mutation. This approach also works with slices of arrays, which is useful when you want to pass only part of the data without creating a new array.

Choosing the Right Parameter Type

The choice between a plain array, params, and ReadOnlySpan<T> depends on the calling pattern and whether mutation is allowed.

Parameter typeCaller syntaxMutation allowedBest fit
int[]Pass an array variableYesGeneral-purpose array handling
params int[]Pass individual valuesYesVariable-length argument lists
ReadOnlySpan<int>Pass array or sliceNoRead-only processing, performance-sensitive code

Use a plain array when the method needs to modify elements or when the caller already has an array. Use params when you want callers to pass a flexible number of arguments without building an array themselves. Use ReadOnlySpan<T> when the method only reads data and you want to prevent accidental mutation or pass slices.

Common Mistakes with Array Parameters

A frequent misunderstanding is assuming that assigning a new array inside the method affects the caller. As shown earlier, it does not unless you use ref. Another mistake is treating array elements as if they were passed by reference when they are not. Passing data[0] to a method passes a copy of that element for value types, so modifying the parameter inside the method does not change the array.

public static void ModifyValue(int value) { value = 100; } int[] data = { 1, 2, 3 }; ModifyValue(data[0]); Console.WriteLine(data[0]); // 1

If you need to modify an element in place, pass the array itself or use ref on the element. Also check for null arrays before iterating, because a method that accepts an array can receive null just like any other reference type.

The behavior of array parameters in C# is consistent with reference-type semantics: the reference is copied, the object is shared. Understanding that distinction prevents the most common bugs when designing methods that accept arrays.

c# pass array to method: Practical Usage and Code Examples | RYUSLOG DEV