Domanda

Sto cercando di costruire un oggetto che assomigli a questo:

  public class MyObject
  {
    private IList<AnotherObject> items;
    public List<AnotherObject> Items
    {
      return items.AsEnumerable().ToList<AnotherObject>();
    }
  }

Sto usando NHibernate come il mio DAL e lo sto mappando direttamente sul campo degli elementi e tutto ciò che funziona bene.

Uso anche Windows Workflow e l'attività del replicatore non funziona con IList generico. ( http: // social .msdn.microsoft.com / Forums / it-US / windowsworkflowfoundation / thread / 2ca74b60-fd33-4031-be4b-17a79e9afe63 ) Questo mi sta praticamente costringendo ad usare l'Elenco < > wrapper invece di IList < > ;. Questo ovviamente interrompe il mapping diretto di NHibernate poiché l'implementazione IList di NHibernate non può essere trasmessa direttamente a un elenco.

** EDIT: il requisito del flusso di lavoro di Windows in realtà significa che perderò l'accesso sicuro all'elenco all'elenco, indipendentemente da ciò che richiede un IList.

Ora l'obiettivo è serializzare / deserializzare questo oggetto. Funziona bene con la serializzazione binaria, ma gli oggetti proxy NHibernate sottostanti esplodono con errori nibernati quando provo a deserializzarli.

Quindi ho provato la serializzazione xml. La serializzazione funziona bene e mi dà le mie piacevoli definizioni di classe concrete nel file xml serializzato che elimina completamente i proxy negligenti. Tuttavia, quando si tenta di deserializzare questo, non sono in grado di aggiungere gli elementi all'elenco come gli articoli. La chiamata AsEnumerable.ToList non consente agli elementi di essere aggiunti all'elenco sottostante tramite il metodo .Add.

Qualcuno ha qualche idea su questo? Sto andando in questo modo nel modo sbagliato?

** EDIT: la classe di calcestruzzo NHibernate è NHibernate.Collection.Generic.PersistentGenericBag che implementa direttamente IList. Tuttavia, ho perso tutti i vantaggi di tipo sicuro dell'elenco generico. Questo mi riporta nel regno di dover scrivere un wrapper per ogni oggetto figlio e volevo davvero evitarlo, se possibile.

È stato utile?

Soluzione

L'opzione è creare la propria implementazione CustomList che è un wrapper attorno a un'istanza che implementa IList

cioè:

public CustomList<AnotherObject> Items    
{      
    return new CustomList<AnotherObject>(items); 
}

vale a dire. quando aggiungi alla tua CustomList < T > si aggiunge alla backing list.

Sembra che fintanto che la tua classe implementa IList e IList < T > starai bene.

Altri suggerimenti

Sì, sfortunatamente non puoi farlo in questo modo. La chiamata a ToList () crea una nuova istanza dell'elenco, quindi quando aggiungi elementi a quell'istanza non si rifletteranno nell'elenco originale (come hai chiaramente scoperto).

Non utilizzo NHibernate, ma sarei curioso di vedere se il tuo contenitore implementa IList (la versione non generica). Dal thread a cui hai fatto riferimento, sembra che System.Collections.IList sia ciò che è effettivamente richiesto (e che è implementato da List < T > , motivo per cui funziona). Il tuo contenitore implementa IList ?

Non puoi semplicemente lanciarlo in questo modo?

public class MyObject
{
    private IList<AnotherObject> items;
    public List<AnotherObject> Items()
    {
        return (List<AnotherObject>)items;
    }
}

Non ho avuto la possibilità di provarlo, ma penso che dovrebbe funzionare!

Penso che la raccolta NHibernate PersistentBag (non generica) implementa IList in modo da poter digitare gli elementi come IList anziché IList < AnotherObject > . Il link nella tua domanda afferma che il problema è che il replicatore richiede un IList che List < T > implementa ma IList < T > non (vai alla figura).

Può essere trasmesso a IEnumerable < T > ;? Puoi provare questo:

public class MyObject
{
    private IList<AnotherObject> items;
    public List<AnotherObject> Items
    {
        return new List<AnotherObject>items.Cast<AnotherObject>());
    }
    // or, to prevent modifying the list
    public IEnumerable<AnotherObject> Items
    {
        return items.Cast<AnotherObject>();
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top