Domanda

Se ho:

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?

Ho eseguito codice simile a questo in Visual Studio 2008 e ho impostato i punti di interruzione dopo ogni esecuzione. Dopo myList1 = getMeAList();, myList1 contiene quattro stringhe e ho premuto il pulsante più per assicurarmi che non fossero tutti nulli.

Dopo myList2 = getMeAnotherList();, myList2 contiene sei stringhe e ho verificato che non fossero nulle ... Dopo myList1.Concat(myList2); myList1 conteneva solo quattro stringhe. Perché?

È stato utile?

Soluzione

Concat restituisce una nuova sequenza senza modificare l'elenco originale . Prova myList1.AddRange(myList2).

Altri suggerimenti

Prova questo:

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

Concat restituisce un IEnumerable < T gt; cioè le due liste messe insieme, non modifica nessuna delle liste esistenti. Inoltre, poiché restituisce un IEnumerable, se si desidera assegnarlo a una variabile che è List & Lt; T & Gt ;, dovrete chiamare ToList () su IEnumerable & Lt; T gt &; che viene restituito.

targetList = list1.Concat(list2).ToList();

Funziona bene, penso di si. Come detto in precedenza, Concat restituisce una nuova sequenza e durante la conversione del risultato in Elenco, esegue il lavoro perfettamente.

Vale anche la pena notare che Concat funziona a tempo costante e in memoria costante. Ad esempio, il seguente codice

        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);

fornisce le seguenti metriche di tempismo / memoria:

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

So che questo è vecchio ma mi sono imbattuto in questo post pensando rapidamente che Concat sarebbe stata la mia risposta. L'unione ha funzionato alla grande per me. Nota, restituisce solo valori univoci ma sapendo che stavo ottenendo valori unici comunque questa soluzione ha funzionato per 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;
        }
    }
}

L'output è:

One
Two
Three
1234
4567

guarda la mia implementazione its 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(); 
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top