Visualizzazione dei risultati da 1 a 4 su 4
  1. #1
    Utente di HTML.it L'avatar di Veronica80
    Registrato dal
    May 2006
    Messaggi
    2,110

    [VB.NET] - Usare LINQ su un oggetto Dictionary

    Ciao a tutti!
    Io uso un oggetto dictionary come datasource per una combobox.
    In questo modo:

    codice:
    Dim mioDict As New Dictionary(Of Integer, String)
    mioDict.Add(0, "Utente")
    mioDict.Add(1, "Moderatore")
    mioDict.Add(2, "Amministratore")
    mioDict.Add(3, "Tecnico")
    miaCmb.DataSource = New BindingSource(mioDict, Nothing)
    miaCmb.ValueMember = "key"
    miaCmb.DisplayMember = "value"
    tutto funziona a meraviglia.
    Ho però necessità di filtrare i dati del dictionary alchè ho pensato di usare LINQ procedendo così:

    codice:
      Dim newDict As Dictionary(Of Integer, String) = mioDict.where(Function(l) l.Key < 2 )
    Ho quindi voluto filtrare i risultati per le item con la key inferiore a 2.
    Però ricevo questo errore:

    Impossibile eseguire il cast di oggetti di tipo 'WhereEnumerableIterator`1[System.Collections.Generic.KeyValuePair`2[System.Int32,System.String]]' sul tipo 'System.Collections.Generic.Dictionary`2[System.Int32,System.String]'.

    Cosa sbaglio?!?

  2. #2
    Moderatore di Windows e software L'avatar di URANIO
    Registrato dal
    Dec 1999
    residenza
    Casalpusterlengo (LO)
    Messaggi
    1,255
    Il problema è che LINQ non ti restituisce l'Oggetto di partenza (lo dice anche l'errore).
    Probabilmente te la cavi con un qualcosa del genere
    Dim newDict = mioDict.where(Function(l) l.Key < 2 ).toArray

  3. #3
    Utente di HTML.it L'avatar di cassano
    Registrato dal
    Aug 2004
    Messaggi
    3,000
    Esatto l'errore dice tutto.

  4. #4
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,296
    Quote Originariamente inviata da Veronica80 Visualizza il messaggio
    Ho però necessità di filtrare i dati del dictionary alchè ho pensato di usare LINQ procedendo così:

    codice:
      Dim newDict As Dictionary(Of Integer, String) = mioDict.where(Function(l) l.Key < 2 )
    Ho quindi voluto filtrare i risultati per le item con la key inferiore a 2.
    Però ricevo questo errore:

    Impossibile eseguire il cast di oggetti di tipo 'WhereEnumerableIterator`1[System.Collections.Generic.KeyValuePair`2[System.Int32,System.String]]' sul tipo 'System.Collections.Generic.Dictionary`2[System.Int32,System.String]'.
    Devi tenere sempre presente che una espressione LINQ, creata usando uno dei tanti suoi metodi (es. Where()), crea come risultato un oggetto che rappresenta l'espressione stessa.

    Quando scrivi
    codice:
      mioDict.where(Function(l) l.Key < 2 )
    stai creando un oggetto che rappresenta una espressione, sempre valorizzata, la quale partendo da un dizionario quindi da un contenitore di coppie chiave/valore, andrebbe a recuperare solo gli elementi che soddisfano un filtro (dato dall'uso di Where()) il quale indica che la chiave di tipo intero deve essere inferiore a 2.

    Questo indicato sopra è tutto ciò che ottieni come valore di ritorno dall'espressione che tu hai scritto.
    Uso infatti il termine "andrebbe" perché finché non viene eseguita in qualche modo, quella espressione rimane tale e non calcola né estrae né filtra nulla, fino a quando non viene attivata.

    Ottieni quindi una espressione che, sottoposta a enumerazione (es. ciclo For, chiamate a ToList(), ToArray(), oppure First(), Last() oppure ancora ToDictionary(), Count(), ecc.), viene eseguita in quel momento e produce i risultati richiesti effettivamente.

    Riassumendo quindi, di sicuro l'espressione non produce un dizionario automaticamente, quindi l'assegnazione che hai fatto a una variabile di tipo Dictionary(Of Integer, String) è sbagliata. Come giustamente indicato nell'errore, il valore del tipo di ritorno è una "enumerazione di oggetti KeyValuePair". Se vuoi eseguire l'espressione e accedere ai risultati, devi quindi leggere il primo valore estraendolo dall'enumerazione e passando ai successivi, con una delle tecniche indicate sopra. Se vuoi ottenere un dizionario con i valori estratti, allora usa il metodo ToDictionary().

    Tieni inoltre conto che il valore restituito potrebbe essere una interfaccia, es. IDictionary, ma in questi casi il mio suggerimento è quello di sfruttare la Type Inference ossia dichiarare la variabile facendole assumere automaticamente il tipo restituito dall'espressione, senza indicarlo.

    Riepilogando, il codice va trasformato in questo modo:
    codice:
      Dim newDict = mioDict.where(Function(l) l.Key < 2 ).ToDictionary()
    Un consiglio: documentati bene su LINQ e su come si usa.

    Ciao!
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.