Due approcci esistenti sono per vedere se l'oggetto implementa IEnumerable<T>
o per verificare il tipo del primo elemento nel set. Il primo si basa sull'oggetto che attualmente implementa IEnumerable<T>
e il secondo funziona solo se tutti gli elementi nella sequenza sono dello stesso tipo derivato.
Una domanda interessante che si potrebbe chiedere è quali tipi hanno tutti gli elementi in comune o qual è il tipo più stretto comune a tutti gli elementi.
Iniziamo con un semplice metodo di supporto. Dato un tipo restituirà una sequenza di quel tipo e tutti i suoi tipi di base.
public static IEnumerable<Type> getBaseTypes(Type type)
{
yield return type;
Type baseType = type.BaseType;
while (baseType != null)
{
yield return baseType;
baseType = baseType.BaseType;
}
}
successivo avremo un metodo per ottenere tutti i tipi comuni di una sequenza dalla prima trovare tutti i tipi più derivati, ottenendo quindi tutti i tipi di base per ogni tipo nella sequenza, e, infine, utilizzando intersect
per ottenere solo gli elementi che tutti hanno in comune:
public static IEnumerable<Type> getCommonTypes(IEnumerable source)
{
HashSet<Type> types = new HashSet<Type>();
foreach (object item in source)
{
types.Add(item.GetType());
}
return types.Select(t => getBaseTypes(t))
.Aggregate((a, b) => a.Intersect(b));
}
si noti che l'ordinamento dei tipi nel primo metodo è dalla maggior parte deriva da almeno derivati, e Intersect
mantiene ordinamento, in modo che la sequenza risultante sarà in ordine dalla maggior parte derivata a meno derivata. Se si desidera trovare il tipo più stretto comune a tutti questi tipi, è sufficiente utilizzare First
sul risultato di questo metodo. (Si noti che poiché tutto deriva da object
ci sarà sempre almeno un tipo restituito qui a meno che non ci siano articoli nell'originale IEnumerable
.
@Arran, che si riferisce alla versione generica –
@Arran: Non necessariamente, se c'è qualsiasi significato sotto l'aspetto che l'OP mostra un array di 'Nullable', ma vuole recuperare 'int'. –
Ah vero, ignorami :) – Arran