2015-05-27 40 views
10

I have IEnumerable<object> tipo variabile.Verificare se IEnumerable <object> è IEnumerable <int>

IEnumerable<object> items= new object[] { 1, 2, 3 }; 

Qual è il modo migliore per verificare se è IEnumerable<int>?

ho cercato

typeof(IEnumerable<int>).IsAssignableFrom(items.GetType()) 
typeof(IEnumerable<int>).IsInstanceOfType(items) 
items is IEnumerable<int> 

Ma, Re-Sharper lamenta tutti.

Nel mio caso, IEnumerable<object> items è di tipo IEnumerable<int> in nella maggior parte dei casi. E volevo realizzare qualcosa quando è di tipo IEnumerable<int> e qualcos'altro per altri tipi.

+4

Ogni elemento in 'elementi' può essere di qualsiasi tipo, quindi è necessario controllare ogni elemento singolarmente. Il controllo che fai ora si applica solo a * tipi * non al contenuto. –

+3

Che cosa stai cercando di ottenere? Immagino che il più semplice sarebbe 'valueA.All (item => item is int)' ma suona più come un problema xy – Sayse

+0

IEnumerable è il 'IEnumerable ' nella maggior parte dei casi, volevo fare qualcosa quando è di tipo 'IEnumerable ' e qualcos'altro per altri tipi. – ANewGuyInTown

risposta

12

Se si desidera controllare se un IEnumerable<object> contiene solo interi, è possibile utilizzare Enumerable.All:

var isInts = items.All(x => x is int); 
+1

Quindi, questo passerà in rassegna tutti i valori negli 'elementi' e controllerà il suo tipo. Stavo cercando una soluzione più "pronta per l'uso", ma potrei aspettarmi troppo. Grazie per la tua risposta. Potrei dover ricorrere a questo. – ANewGuyInTown

+1

@ANewGuyInTown Se sai * di sicuro * che tutti gli elementi sono dello stesso tipo, puoi usare "Qualsiasi" - si fermerà dopo la prima iterazione. –

+0

@GertArnold Ma questo punto è che lui * non * sa :) –

3

È possibile utilizzare Cast O OfType come questo:

Proprio dovrebbe preoccuparsi di:

OfType: Restituire solo gli elementi di tipo x.

Cast: Proverà a trasmettere tutti gli elementi in tipo x. se alcuni di loro non sono da questo tipo si ottiene InvalidCastException

items.Cast<int>(); 

o

items.OfType<int>(); 
+1

Nota: Di tipo non restituirà necessariamente la stessa lista e sebbene questo risponda al titolo, non risponde alla domanda. – Sayse

+0

Non voglio 'cast' in una lista/enumerable diversa, voglio solo' check' – ANewGuyInTown

+1

@ANewGuyInTown il controllo non ha senso. Hai definito una variabile che può contenere qualsiasi cosa - sia stringhe che int. Non esiste alcun tipo o relazione di ereditarietà tra questo un IEnumerable

5

Perché Valuetypes do not support co or contravariance. IEnumerable<object> non può essere un IEnumerable<int> - l'hai provato da solo perché dovevi utilizzare un cast per produrre il tuo IEnumerable<object>, che in realtà racchiudeva tutti i valori int. R # riporta quindi correttamente un tipogreck sospetto perché deriva dalle tue azioni che i tuoi assegni restituiranno sempre false.

Quindi, alla fine, è necessario verificare singolarmente ogni elemento se si tratta di un int prima di utilizzare un cast o si verificherà un'eccezione.

1

Non puoi lanciare una generica ad un altro, proprio perché il tipo è una classe base dell'altro. Quindi non vi è alcuna possibilità di ottenere un Enumerable<int> da un Enumerable<object>. Re-Sharper si lamenta perché le espressioni non torneranno mai vere.

voi hanno

IEnumerable<object> items= ((IEnumerable)valueA).Cast<object>(); 

Forse sapete che il vostro valoreA è pieno di numeri interi, ma si è permesso di mettere stringhe o galleggia sulla tua items anche. Quindi il compilatore non può sapere con certezza che la lista sia un numero enumerabile di interi.

modo da avere per creare un nuovo enumerabile, come Peyman risposta prima (che non è una nuova lista, solo un altro enumerabile):

items.OfType<int>(); 

questo restituirà solo gli elementi che sono interi e assicura che si può ottenere un Enumerable<int>

Problemi correlati