Array Merging
.NET Development
C# Programming
Data Structures
Software Engineering

Merging two arrays in .NET

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Merging arrays in .NET can be done in several ways depending on performance needs and readability goals. For small datasets, LINQ is expressive and concise. For large arrays or tight loops, direct copying is usually faster and creates less overhead.

Simple Merge with LINQ

Concat is the most readable option and works for many business applications.

csharp
1using System;
2using System.Linq;
3
4class Program
5{
6    static void Main()
7    {
8        int[] a = { 1, 2, 3 };
9        int[] b = { 4, 5, 6 };
10
11        int[] merged = a.Concat(b).ToArray();
12        Console.WriteLine(string.Join(", ", merged));
13    }
14}

This is clear and maintainable, but it creates iterator overhead before materialization.

High Performance Merge with Array.Copy

For hot paths, preallocate the destination array and copy both sources directly.

csharp
1using System;
2
3class Program
4{
5    static int[] Merge(int[] left, int[] right)
6    {
7        var result = new int[left.Length + right.Length];
8        Array.Copy(left, 0, result, 0, left.Length);
9        Array.Copy(right, 0, result, left.Length, right.Length);
10        return result;
11    }
12
13    static void Main()
14    {
15        int[] x = { 10, 20, 30 };
16        int[] y = { 40, 50 };
17
18        int[] merged = Merge(x, y);
19        Console.WriteLine(string.Join(" | ", merged));
20    }
21}

This approach avoids LINQ iterator chains and is often the best baseline for performance sensitive code.

List and AddRange for Incremental Construction

If you merge multiple arrays over time, a List can simplify accumulation.

csharp
1using System;
2using System.Collections.Generic;
3
4class Program
5{
6    static void Main()
7    {
8        int[] a = { 1, 2 };
9        int[] b = { 3, 4 };
10        int[] c = { 5, 6 };
11
12        var list = new List<int>(a.Length + b.Length + c.Length);
13        list.AddRange(a);
14        list.AddRange(b);
15        list.AddRange(c);
16
17        int[] merged = list.ToArray();
18        Console.WriteLine(string.Join(",", merged));
19    }
20}

Reserve capacity up front when possible to reduce reallocations.

Choosing the Right Method

Use LINQ when code clarity matters most and data size is moderate. Use Array.Copy when profiling shows merge overhead in critical sections. Use List for variable count merges where source arrays are not all known at once.

Also consider whether arrays should be deduplicated or sorted after merge. If unique values are required, a set based approach may be more appropriate than plain concatenation.

For memory constrained contexts, avoid unnecessary intermediate arrays. Precompute final size and allocate once.

You can also implement a generic merge helper for reusable library code. Generic methods keep call sites clean and support many element types without duplication.

csharp
1public static T[] MergeArrays<T>(T[] left, T[] right)
2{
3    if (left == null) throw new ArgumentNullException(nameof(left));
4    if (right == null) throw new ArgumentNullException(nameof(right));
5
6    var output = new T[left.Length + right.Length];
7    Array.Copy(left, 0, output, 0, left.Length);
8    Array.Copy(right, 0, output, left.Length, right.Length);
9    return output;
10}

When using modern runtimes, Span and CopyTo can improve clarity for memory oriented code paths. They are especially useful when merging slices from larger buffers in parsers or protocol handlers.

If merge logic becomes a bottleneck, benchmark alternatives with BenchmarkDotNet on production like input sizes. Compare allocation count and throughput, not only wall clock time, since GC behavior often determines real service latency.

Common Pitfalls

A common pitfall is calling Concat repeatedly inside loops and materializing each time. This creates many transient allocations and poor throughput.

Another issue is forgetting null checks on input arrays. Defensive validation can prevent runtime failures in service boundaries.

Developers also mix arrays of incompatible element types and then rely on casts. Prefer strongly typed merge helpers to keep compile time safety.

Finally, failing to preallocate destination size can cause repeated growth when using lists. Set initial capacity when you can estimate final length.

Summary

  • LINQ Concat is concise and good for general use cases.
  • Array.Copy is usually fastest for two array merges.
  • List with AddRange works well for incremental multi array builds.
  • Choose based on workload profile, not style preference alone.
  • Preallocation and reduced intermediate allocations improve performance and reliability.

Course illustration
Course illustration

All Rights Reserved.