Merging arrays is one of the most common operations in C#-but how you merge them changes depending on what you’re building. Beginners often think there is only one way to combine two arrays, but in reality, C# gives you multiple merging techniques, each with different performance characteristics, use-cases, and internal behaviours.
This guide explains:
✅ Every major way to merge arrays
✅ How they work internally (copying, memory layout, resizing)
✅ Beginner, intermediate, and advanced examples
✅ LINQ merging, distinct merges, sorted merges, interleaving, flattening
✅ When to use arrays vs List<T> vs Span<T>
…and much more.
Let’s begin.
1. Understanding Arrays in C# Before You Merge Them
Before merging, you should understand how arrays behave in C#:
🔹 Arrays are fixed-size
Once created, you cannot directly resize an array. To “resize,” .NET creates a new array and copies items across.
🔹 Arrays store elements in contiguous memory
This means accessing an element is extremely fast (O(1)), but inserting or merging requires copying (O(n)).
🔹 Copies always allocate new memory
Every merge technique eventually boils down to:
- Create a new array of size
a.Length + b.Length - Copy
ainto the new array - Copy
binto the new array
Some methods automate this for you (like LINQ), but this is always what’s happening under the hood.
2. The Most Common Method: Using Concat() (LINQ)
⭐ Best for: readability, simplicity, beginner friendliness
❌ Not best for: performance-critical or high-allocation code
int[] a = { 1, 2, 3 };
int[] b = { 4, 5, 6 };
int[] merged = a.Concat(b).ToArray();
What’s happening behind the scenes
Concat()creates a lazy sequence (it doesn’t merge yet).ToArray()forces the merge by:- calculating the total length
- allocating a new array
- copying both arrays sequentially
Pros
✔ Very clean
✔ No manual loop needed
✔ Easy to chain with .Distinct(), .OrderBy(), etc.
Cons
✘ Creates an iterator + a new array
✘ Not the fastest option
3. Fastest Manual Method: Using Array.Copy()
⭐ Best for: performance, control, large arrays
int[] a = { 1, 2, 3 };
int[] b = { 4, 5, 6 };
int[] merged = new int[a.Length + b.Length];
Array.Copy(a, merged, a.Length);
Array.Copy(b, 0, merged, a.Length, b.Length);
Why this is faster
Array.Copy()uses highly optimized internal memory copying- No iterator overhead
- Only a single array allocation
Pros
✔ Fastest merging approach
✔ Precise control
✔ Good for performance-critical code
Cons
✘ More code to write
✘ Not as readable for beginners
4. Merge Using a List<T> (Most Flexible)
⭐ Best for: dynamic merging, unknown number of arrays, convenience
int[] a = { 1, 2, 3 };
int[] b = { 4, 5, 6 };
List<int> mergedList = new List<int>(a.Length + b.Length);
mergedList.AddRange(a);
mergedList.AddRange(b);
int[] merged = mergedList.ToArray();
Why use lists?
- Lists auto-resize
- You can add filters, conditions, remove items
- Best when merging >2 arrays or merging in loops
Pros
✔ Flexible
✔ Easy to extend
✔ Best for dynamic merging
Cons
✘ Slightly more overhead
✘ Still ends in .ToArray() copy
5. Merge With LINQ + Conditions (Filter While Merging)
⭐ Best for: merging only certain elements
int[] a = { 1, 2, 3, 10 };
int[] b = { 4, 5, 6, 12 };
int[] mergedEven = a
.Concat(b)
.Where(x => x % 2 == 0)
.ToArray();
This merges AND filters in one expression.
6. Merge and Remove Duplicates (Distinct())
int[] mergedDistinct = a.Concat(b).Distinct().ToArray();
Under the hood:
- Builds a hash set
- Removes duplicates
- Converts back to array
7. Merge and Sort
int[] mergedSorted = a.Concat(b).OrderBy(x => x).ToArray();
8. Advanced: Interleave Two Arrays
(Useful for zipping data: e.g., alternating items)
Example output
a = {1,3,5}b = {2,4,6}
→ {1,2,3,4,5,6}
Code:
int[] Interleave(int[] a, int[] b)
{
int length = a.Length + b.Length;
int[] result = new int[length];
int ai = 0, bi = 0, ri = 0;
while (ai < a.Length || bi < b.Length)
{
if (ai < a.Length) result[ri++] = a[ai++];
if (bi < b.Length) result[ri++] = b[bi++];
}
return result;
}
9. Advanced: Merge Multiple Arrays (N Arrays)
int[][] inputs = {
new[] {1, 2},
new[] {3, 4},
new[] {5, 6}
};
int[] merged = inputs.SelectMany(x => x).ToArray();
SelectMany = flatten array-of-arrays
10. Mega-Fast: Use Span<T> (Advanced .NET technique)
⭐ For: high-performance merging with minimal overhead
(Usually in game engines, financial systems, HPC)
int[] merged = new int[a.Length + b.Length];
Span<int> span = merged;
a.AsSpan().CopyTo(span);
b.AsSpan().CopyTo(span[a.Length..]);
Why it’s fast
- Uses stack-friendly views over memory
- Avoids bounds checks
- No enumerators
This is the closest to “manual memory-level merging” in managed code.
11. When NOT to Use Arrays (Important!)
Choose List<T> or IEnumerable<T> if:
- You don’t know final size in advance
- You need to frequently add/remove
- You’re combining dozens/hundreds of arrays
- You’re working with streams of data
Arrays are best ONLY when:
- Size is fixed
- Highest speed is required
- Memory layout matters (interop, unsafe, HPC)
12. Which Method Should I Use?
Fastest
➡️ Array.Copy()
Cleanest code
➡️ Concat().ToArray()
Most flexible
➡️ List<T>.AddRange()
For filtering while merging
➡️ Concat().Where()
For deduplication
➡️ .Distinct()
For advanced performance
➡️ Span<T>
13. Complete Practical Example (All Methods Together)
int[] a = { 1, 2, 3 };
int[] b = { 4, 5, 6 };
// 1. Simple merge
var m1 = a.Concat(b).ToArray();
// 2. Fast merge
var m2 = new int[a.Length + b.Length];
Array.Copy(a, m2, a.Length);
Array.Copy(b, 0, m2, a.Length, b.Length);
// 3. List merge
var list = new List<int>(a.Length + b.Length);
list.AddRange(a);
list.AddRange(b);
var m3 = list.ToArray();
// 4. Distinct + sorted
var m4 = a.Concat(b).Distinct().OrderBy(x => x).ToArray();
// 5. Interleave
var m5 = Interleave(a, b);
// 6. Multi-array flatten
int[][] multi = { a, b, new[] { 7, 8 } };
var m6 = multi.SelectMany(x => x).ToArray();