IList.Cast<typeof(T)>() restituisce un errore, la sintassi sembra corretta
-
09-06-2019 - |
Domanda
public static IList<T> LoadObjectListAll<T>()
{
ISession session = CheckForExistingSession();
var cfg = new NHibernate.Cfg.Configuration().Configure();
var returnList = session.CreateCriteria(typeof(T));
var list = returnList.List();
var castList = list.Cast<typeof(T)>();
return castList;
}
Quindi, ricevo un errore di compilazione in cui sto trasmettendo l'elemento "list" a un IList generico ....qualcuno può vedere un errore evidente qui?
Soluzione
T
non è un tipo né a System.Type
. T
è un parametro di tipo. typeof(T)
restituisce il tipo di T
.IL typeof
non agisce su un oggetto, restituisce il file Type
oggetto di un tipo. http://msdn.microsoft.com/en-us/library/58918ffs.aspx
@John ha ragione nel rispondere alla tua domanda diretta.Ma il codice di NHibernate è un po' fuori posto.Non dovresti configurare il file ISessionFactory
Dopo ottenere il ISession
, Per esempio.
public static T[] LoadObjectListAll()
{
var session = GetNewSession();
var criteria = session.CreateCriteria(typeof(T));
var results = criteria.List<T>();
return results.ToArray();
}
Altri suggerimenti
Penso
var castList = list.Cast<typeof(T)>();
dovrebbe essere
var castList = list.Cast<T>();
@Jon limjap L'errore più evidente che posso vedere è che un
IList
è decisamente diverso da unIList<T>
.UNIList
non è generico (ad es.ArrayList
).
La domanda originale stava già utilizzando un file IList<T>
.È stato rimosso quando qualcuno ha modificato la formattazione.Probabilmente un problema con Markdown.
Risolto ora.
L'IList è un IList<T>, è stato semplicemente infastidito dal ribasso quando l'ha pubblicato.Ho provato a formattarlo, ma mi è mancato l'escape <T>.. Ora lo risolvo.
La CLI supporta solo argomenti generici per covarianza e controvarianza quando si utilizzano i delegati, ma quando si utilizzano i generici ci sono alcune limitazioni, ad esempio è possibile eseguire il cast di una stringa su un oggetto, quindi la maggior parte delle persone presumerà che si possa fare lo stesso con List to a List ma non puoi farlo perché non esiste covarianza tra parametri generici, tuttavia puoi simulare la covarianza come puoi vedere in questo articolo.Quindi dipende dal tipo di runtime generato dalla fabbrica astratta.
Sembra una catena di Markov...Bravo.
T è già un parametro di tipo, non è necessario chiamarlo typeof.TypeOf accetta un tipo e restituisce il relativo parametro di tipo.
"La domanda originale utilizzava già un file IList<T>
.È stato rimosso quando qualcuno ha modificato la formattazione.Probabilmente è un problema con Markdown."
Questo è quello che ho visto ma è stato modificato da qualcuno e questo è il motivo per cui ho inserito la mia spiegazione sulla covarianza ma per qualche motivo sono stato contrassegnato a -1.
Hai troppe variabili temporanee che creano confusione
invece di
var returnList = session.CreateCriteria(typeof(T));
var list = returnList.List();
var castList = list.Cast<typeof(T)>();
return castList;
Basta fare
return session.CreateCriteria(typeof(T)).List().Cast<T>();
@Jonathan Olanda
T è già un parametro di tipo, non è necessario chiamarlo typeof.TypeOf accetta un tipo e restituisce il relativo parametro di tipo.
typeof
"prende" un tipo e lo restituisce System.Type
La CLI supporta solo argomenti generici per covarianza e controvarianza quando si utilizzano i delegati, ma quando si utilizzano i generici ci sono alcune limitazioni, ad esempio è possibile eseguire il cast di una stringa su un oggetto, quindi la maggior parte delle persone presumerà che si possa fare lo stesso con List<string>
ad a List<object>
ma non puoi farlo perché non esiste covarianza tra parametri generici, tuttavia puoi simulare la covarianza come puoi vedere in questo articolo.Quindi dipende dal tipo di runtime generato dalla fabbrica astratta.
@Jon e @Jonathan hanno ragione, ma devi anche cambiare il tipo di ritorno in
IList<T>
Anche.A meno che non si tratti solo di un bug di ribasso.
@Jonathan, immaginavo che fosse così.
Non sono sicuro della versione di nHibernate che stai utilizzando.Non ho ancora provato la versione gold della 2.0, ma potresti ripulire un po' il metodo, rimuovendo alcune righe:
public static IList<T> LoadObjectListAll()
{
ISession session = CheckForExistingSession();
// Not sure if you can configure a session after retrieving it. CheckForExistingSession should have this logic.
// var cfg = new NHibernate.Cfg.Configuration().Configure();
var criteria = session.CreateCriteria(typeof(T));
return criteria.List<T>();
}
L'errore più evidente che posso vedere è che an IList
è decisamente diverso da un IList<T>
.UN IList
non è generico (ad es. ArrayList
).
Quindi la firma del tuo metodo dovrebbe essere:
public static IList<T> LoadObjectListAll()