11
votes

Pourquoi une collection de est-elle incapable de lancer à un ?

Pourquoi une collection de Enum impossible de se lancer dans un int? xxx


0 commentaires

4 Réponses :


15
votes

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();


5 commentaires

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 : / ... Je suppose {test.a} .Sélectionnez (x => (int?) X ) .Toliste () devrait fonctionner aussi bien?


@Kobi: Voir ma dernière modification - j'ai traversé quelques versions :)


On pourrait également éviter le casting <> () en moulant la valeur deux fois dans la sélection: Sélectionnez (x => (int?) (Int) x) . Cependant, le casting <> () 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 ?: .



-1
votes

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();


0 commentaires

3
votes

C'est parce que casting () fait quelque chose comme: xxx

vous auriez au premier casting () à un int : xxx

ou ne pas utiliser couler () du tout: xxx


10 commentaires

@mgronber: j'ai remarqué. C'est pourquoi je l'ai réparé il y a 3 minutes.


@Jaroslav: Savez-vous pourquoi Cast (). Cast () ne fonctionne pas?


@Homam: à l'intérieurement, le CAST <> () 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 <> Type. Cela fonctionne en interne comme Jaroslav a montré. Le cast () pour test.a est identique que (int?) (Objet) test.a et il sera toujours échouer.


Néanmoins, il est intéressant d'intéresser que couler (). Cast () ne fonctionne pas, car casse (). Sélectionnez (x => x). Cast () fonctionne bien.


@Homam, Mgronber: Mettez simplement le premier énumérateur passe simplement l'objet au prochain énumérateur. int? NI = (int?) Test.A; fonctionne uniquement à cause des optimisations - le compilateur la transformera: int? ni = 1; , aussi int? Ni = (int?) Testa; sera retrouvé comme int? ni = nouveau int? (((int) testa); .


Bien sûr. Le premier couler () renvoie l'objet car il est utilisé via l'interface iEnumerable et que cela finit donc pour être un non-OP.


Euh, ça n'a toujours aucun sens. Le test est déposé sur int avant de passer par ienumerable de sorte que la seconde distribution doit être simple (int?) (Objet) 2 et cela devrait fonctionner.


@mgronber: le couler () ne enveloppe pas un énumérateur, si c'est déjà le type correct. Cast () n'a aucun effet sur l'instance d'énumérateur. C'est dans ce cas la même chose que nouveau [] {test.a} comme iEnumerable . arr.cast (). Cast est donc identique à celui de arr.cast () et depuis ienumerator.moVoNext () jette la valeur à objet d'abord, il jette.


@Jaroslav: OK, je comprends enfin cela. Donc, c'est un no-op si ((iEnumerable) nouveau [] {test.a}) comme IEnumerable n'est pas null. Merci beaucoup pour votre patience :)


@Homam Voir cette question Stackoverflow.com/Questtions/20292623/... et la question suivante ..



0
votes

Cela ne fonctionnerait pas parce que nous devons comprendre ce qui est Enum et qu'est-ce que l'int? (nullable int)

int? n'est pas vraiment un int C'est une instance générique de nullable, - la syntaxe t? est sténographique pour système.Nullable, où T est un type de valeur. Les deux formes sont interchangeables. Lien

Enum Le type de sous-jacents par défaut des éléments d'énumération est INT. link

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.

où comme dans le premier int? x = (int?) Test.A; 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 puis laboxing IT comme int? retourne un int.


0 commentaires