Pourquoi une collection de Enum code> impossible de se lancer dans un
int? code>
4 Réponses :
La méthode code> CAST CODE> ne peut effectuer que les conversions de la boxe / de la boîte de référence, des conversions de référence et des conversions entre un type d'énumjet et son type intégré sous-jacent. La boîte de consigne doit être au bon type cependant - il ne peut pas créer un Box à un type nullable (contrairement à la conversion C #).
// Fails var collection1 = new object[] { Test.A }.Select(x => (int?) x) .ToList();
Intéressant. Je ne me souviens pas jamais de coulée à l'aide de Linq de cette façon, je n'utilise que des types connus : / code> ... Je suppose
{test.a} .Sélectionnez (x => (int?) X ) .Toliste () code> devrait fonctionner aussi bien?
@Kobi: Voir ma dernière modification - j'ai traversé quelques versions :)
On pourrait également éviter le casting <> () code> en moulant la valeur deux fois dans la sélection:
Sélectionnez (x => (int?) (Int) x) code>. Cependant, le
casting <> () code> est nécessaire si la collection implémente seulement une iénumérable non générique.
@mgronber: oui les deux comptes :)
Remarque: il est très simple de le faire fonctionner avec des collections d'objets à l'aide de l'opérateur conditionnel ?: Code>.
Je ne sais pas pourquoi casting () code> ne fonctionne pas mais vous pouvez utiliser
SELECT () code> pour faire ce que vous voulez.
var collection = new[] { Test.A }.Select(item => (int?)item).ToList();
C'est parce que vous auriez au premier ou ne pas utiliser casting () code> fait quelque chose comme:
casting () code> à un int : p>
couler () code> du tout: p>
@mgronber: j'ai remarqué. C'est pourquoi je l'ai réparé il y a 3 minutes.
@Jaroslav: Savez-vous pourquoi Cast
@Homam: à l'intérieurement, le CAST <> () CODE> BOCE La valeur à l'objet avant de la jeter sur le type de cible et que vous ne pouvez pas lancer encadré Enum directement sur
Nullable <> Code> Type. Cela fonctionne en interne comme Jaroslav a montré. Le
cast
test.a code> est identique que
(int?) (Objet) test.a code> et il sera toujours échouer.
Néanmoins, il est intéressant d'intéresser que couler
casse
@Homam, Mgronber: Mettez simplement le premier énumérateur passe simplement l'objet code> au prochain énumérateur.
int? NI = (int?) Test.A; Code> fonctionne uniquement à cause des optimisations - le compilateur la transformera:
int? ni = 1; code>, aussi
int? Ni = (int?) Testa; code> sera retrouvé comme
int? ni = nouveau int? (((int) testa); code>.
Bien sûr. Le premier couler
iEnumerable code> et que cela finit donc pour être un non-OP.
Euh, ça n'a toujours aucun sens. Le test code> est déposé sur
int code> avant de passer par
ienumerable code> de sorte que la seconde distribution doit être simple
(int?) (Objet) 2 code> et cela devrait fonctionner.
@mgronber: le couler () code> ne enveloppe pas un énumérateur, si c'est déjà le type correct.
Cast
nouveau [] {test.a} comme iEnumerable
arr.cast
arr.cast
ienumerator.moVoNext () code> jette la valeur à
objet code> d'abord, il jette.
@Jaroslav: OK, je comprends enfin cela. Donc, c'est un no-op si ((iEnumerable) nouveau [] {test.a}) comme IEnumerable
@Homam Voir cette question Stackoverflow.com/Questtions/20292623/... et la question suivante ..
Cela ne fonctionnerait pas parce que nous devons comprendre ce qui est Enum et qu'est-ce que l'int? (nullable int) p>
Enum strong> Le type de sous-jacents par défaut des éléments d'énumération est INT. link p>
Par conséquent, une conversion implicite entre Int et Enum existe. Mais la conversion implicite entre une énorme (int) sur NULLLABLE (type de référence entièrement différent) n'existe pas. C'est pourquoi vous voyez une exception InvalidcastException. P>
où comme dans le premier int? x = (int?) Test.A; code> Déclaration Vous forcez la conversion explicite à la boîte de valeur et obtenez un entier ou obtenez un null, ce qui fonctionne, ce qui fonctionne parce que la boxe est enum dans
objet Code> puis laboxing IT comme
int? code> retourne un int. p>