Adding List<T>.Add another list
Object-Oriented Design practice on Codemia
Turn requirements into classes, and defend the design, on the problems that come up in OOD rounds.
Introduction
In C#, List<T>.Add inserts exactly one element of type T. If you want to append every element from another list, the method you usually want is AddRange, not Add.
What Add Actually Does
If the list type is List<int>, then Add expects one int.
That is ordinary single-item insertion. It changes the list length by one.
Use AddRange to Append Another List
If you want all items from another collection appended to the first list, use AddRange.
This is the standard in-place way to combine two lists of the same element type.
Why Add(secondList) Fails
This code does not compile for List<int>:
It fails because first is a List<int>, so Add requires one int, not a List<int>.
The only time Add(secondList) makes sense is when the element type is itself a list, such as List<List<int>>. That is a different structure entirely.
Create a New Combined List Instead of Mutating
If you do not want to modify the original list, copy it first and then append the second list.
This is often the cleanest solution when the original inputs should stay unchanged.
Concat Is a Non-Mutating Alternative
LINQ also offers Concat.
Concat is useful when you are already composing other LINQ operations. AddRange is often clearer when the intent is simply to append one collection to another in place.
Which One Should You Choose?
Use AddRange when:
- you want to mutate the original list,
- you want the most direct list-to-list append operation,
- you are not already in a LINQ pipeline.
Use Concat when:
- you want a non-mutating result,
- you are already composing sequence operations,
- a deferred-sequence style reads more naturally in context.
The important part is to distinguish "append one item" from "append many items."
Common Pitfalls
A common mistake is trying Add(otherList) when the list element type is not itself a list. That is simply the wrong method for the job.
Another issue is mutating a list with AddRange when you actually intended to keep the original untouched.
Developers also sometimes forget ToList() after Concat and then wonder why the result is not a concrete List<T> yet.
Summary
- '
Addinserts one element of typeT.' - '
AddRangeappends all elements from another collection.' - Use
AddRangefor in-place list-to-list appending. - Copy the first list before appending if you need to preserve the original.
- Use
Concatwhen you want a non-mutating LINQ-style combination.
Related reading
- Anyone know a good workaround for the lack of an enum generic constraint?
- Are static methods inherited in Java?
- Argument of type 'awaited T' is not assignable to parameter of type 'T
- Async tasks and Simple Injector Lifetime scopes
- Adding scripting functionality to .NET applications
- Adding string to StringBuilder from async method
- Asynchronous programming design pattern
- Asynchronous Web Request, EntityFramework, and DI, how does it work?

OOD Fundamentals
Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Object-Oriented Design practice on Codemia
Turn requirements into classes, and defend the design, on the problems that come up in OOD rounds.