214

If I have:

List<string> myList1;
List<string> myList2;

myList1 = getMeAList();
// Checked myList1, it contains 4 strings

myList2 = getMeAnotherList();
// Checked myList2, it contains 6 strings

myList1.Concat(myList2);
// Checked mylist1, it contains 4 strings... why?

I ran code similar to this in Visual Studio 2008 and set break points after each execution. After myList1 = getMeAList();, myList1 contains four strings, and I pressed the plus button to make sure they weren't all nulls.

After myList2 = getMeAnotherList();, myList2 contains six strings, and I checked to make sure they weren't null... After myList1.Concat(myList2); myList1 contained only four strings. Why is that?

luk2302
  • 55,258
  • 23
  • 97
  • 137
Matt
  • 5,249
  • 12
  • 40
  • 45

6 Answers6

384

Concat returns a new sequence without modifying the original list. Try myList1.AddRange(myList2).

Community
  • 1
  • 1
John Kugelman
  • 349,597
  • 67
  • 533
  • 578
127

Try this:

myList1 = myList1.Concat(myList2).ToList();

Concat returns an IEnumerable<T> that is the two lists put together, it doesn't modify either existing list. Also, since it returns an IEnumerable, if you want to assign it to a variable that is List<T>, you'll have to call ToList() on the IEnumerable<T> that is returned.

Jonathan Rupp
  • 15,522
  • 5
  • 45
  • 61
16
targetList = list1.Concat(list2).ToList();

It's working fine I think so. As previously said, Concat returns a new sequence and while converting the result to List, it does the job perfectly.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Balasubramani M
  • 7,742
  • 2
  • 45
  • 47
8

It also worth noting that Concat works in constant time and in constant memory. For example, the following code

        long boundary = 60000000;
        for (long i = 0; i < boundary; i++)
        {
            list1.Add(i);
            list2.Add(i);
        }
        var listConcat = list1.Concat(list2);
        var list = listConcat.ToList();
        list1.AddRange(list2);

gives the following timing/memory metrics:

After lists filled mem used: 1048730 KB
concat two enumerables: 00:00:00.0023309 mem used: 1048730 KB
convert concat to list: 00:00:03.7430633 mem used: 2097307 KB
list1.AddRange(list2) : 00:00:00.8439870 mem used: 2621595 KB
Dmitry Andrievsky
  • 1,803
  • 17
  • 20
3

I know this is old but I came upon this post quickly thinking Concat would be my answer. Union worked great for me. Note, it returns only unique values but knowing that I was getting unique values anyway this solution worked for me.

namespace TestProject
{
    public partial class Form1 :Form
    {
        public Form1()
        {
            InitializeComponent();

            List<string> FirstList = new List<string>();
            FirstList.Add("1234");
            FirstList.Add("4567");

            // In my code, I know I would not have this here but I put it in as a demonstration that it will not be in the secondList twice
            FirstList.Add("Three");  

            List<string> secondList = GetList(FirstList);            
            foreach (string item in secondList)
                Console.WriteLine(item);
        }

        private List<String> GetList(List<string> SortBy)
        {
            List<string> list = new List<string>();
            list.Add("One");
            list.Add("Two");
            list.Add("Three");

            list = list.Union(SortBy).ToList();

            return list;
        }
    }
}

The output is:

One
Two
Three
1234
4567
Esaith
  • 706
  • 9
  • 12
3

Take a look at my implementation. It's safe from null lists.

 IList<string> all= new List<string>();

 if (letterForm.SecretaryPhone!=null)// first list may be null
     all=all.Concat(letterForm.SecretaryPhone).ToList();

 if (letterForm.EmployeePhone != null)// second list may be null
     all= all.Concat(letterForm.EmployeePhone).ToList(); 

 if (letterForm.DepartmentManagerName != null) // this is not list (its just string variable) so wrap it inside list then concat it 
     all = all.Concat(new []{letterForm.DepartmentManagerPhone}).ToList();
pushkin
  • 9,575
  • 15
  • 51
  • 95
Basheer AL-MOMANI
  • 14,473
  • 9
  • 96
  • 92