Linq su c#

Ciao a tutti,
Sono nuovo del forum, sto facendo il mio primo programma che utilizza il LINQ, il mio problema e' questo: devo ricavare il primo valore minore a quello di riferimento tra quelli contenuti in una lista.
Ho cominciato a scriver il codice, ma m sono bloccato a causa di 2 errori che non riesco a risolvere.

il mio codice e' questo:

codice:
private void button1_Click(object sender, EventArgs e)
{
XDocument xmlDoc = XDocument.Load(@"c:\a\casse.xml");

var casse = (from serbatoio in xmlDoc.Descendants("serbatoio")
where serbatoio.Attribute("id").Value == ("serbatoio" + NumSerbatoio.Text)
select serbatoio).FirstOrDefault().Descendants("valore")
.Select(v => new { Altezza = int.Parse(v.Attribute("Altezza").Value), Litri = int.Parse(v.Attribute("litri").Value) }).ToList();

var prova = (from altezze in casse
orderby altezze.Altezza descending
select altezze).ToList();

int altezza1 = prova.FirstOrDefault(x => x > int.Parse(Altezza.Text));

// textBox1.Text = casse.ToString();
} visual studio mi restituisce questi errori nell ultima riga:

Errore 1 'System.Collections.Generic.List<AnonymousType#1>' non contiene una definizione per 'FirstOrDefault' e l'overload migliore del metodo di estensione 'System.Linq.ParallelEnumerable.FirstOrDefault(System.Linq.ParallelQuery, System.Func<TSource,bool>)' presenta alcuni argomenti non validi

Errore 2 Argomento dell'istanza: impossibile convertire da 'System.Collections.Generic.List<AnonymousType#1>' a 'System.Linq.ParallelQuery'

potere aiutarmi a risolvere il mio problema per favore?

grazie

Il compilatore ha ragione, x nell'ultima riga è una classe anonima con le proprietà Altezza e Litri, devi esplicitare quale proprietà vuoi confrontare, ad ogni modo crea una classe "normale" e usa quella che rendi più leggibile il codice

Ciao

Ciao in che modo posso esplicitare i valori di altezza?

Cosa intendi per classe "normale"?

Semplicemente una classe

Ciao

intendi senza usare il linq?
puoi spiegarmi come sistemare quegli errori?

Come primo indizio la classe che puoi creare può essere:

    public class Serbatoio
    {
      public int Altezza { get; set; }
      public int Litri { get; set; }
    }

La classe è da utilizzare con LINQ, non devi stravolgere nulla, ma sai cos'è una classe? Lo davo per scontato visto che utilizzi LINQ

Ciao

Secondo suggerimento:
La prima query può diventare con la classe appena creata:

List<Serbatoio> casse = (from serbatoio in xmlDoc.Descendants("serbatoio")
                   where serbatoio.Attribute("id").Value == ("serbatoio" + "NumSerbatoio.Text")
                   select serbatoio).FirstOrDefault().Descendants("valore")
                   .Select(x => new Serbatoio()
                   {
                     Altezza = int.Parse(x.Attribute("Altezza").Value),
                     Litri = int.Parse(x.Attribute("litri").Value)
                   }).ToList();

Per ricavare l'altezza più grande sotto alla soglia ti conviene utilizzare ancora LINQ per una maggiore leggibilità:

int altezza1 = (from p in casse
                      where p.Altezza < int.Parse(Altezza.Text)
                      orderby p.Altezza descending
                     select p.Altezza).FirstOrDefault();

la query associata alla variabile "prova" del codice che avevi postato a questo punto non ti serve e la puoi cancellare
Trovo il codice più pulito con una classe non anonima

Ciao
PS: Nel codice di prima togli da "NumSerbatoio.Text" le virgolette naturalmente

Ciao, grazie del consiglio :slight_smile: appena torno a casa lo provo... si so cosa e' una classe, ma non riuscivo a capire cosa volevi dirmi :*
Ti aggiorno sui miei progressi...a dopo

Funziona perfettamente :slight_smile: grazie di tutto