2010-02-28 7 views
2

Dans une bibliothèque, je crée, je dois utiliser la suite casting:Cast uint -> double invalide?

public void Foo(IList<uint> uintsList) // I need to use uint in the interface for this method 
{ 
    List<double> doublesList = uintsList.Cast<double>().ToList(); 
    // Do something with the doublesList 
} 

Je suppose que uint cast ->double doit toujours être valide, et lors de mon test, il a toujours travaillé très bien.

Mais dans l'application qui utilise cette méthode, le InvalidCastException est apparu. Malheureusement, je n'ai pas accès à cette application. Donc, voici mes questions:

  • Qu'est-ce qui pourrait causer cette exception? Le cast uint-> double n'est-il pas toujours valide?
  • Comment puis-je sécuriser mon algorithme pour éviter cette exception?

EDIT
Bien sûr, avant de lancer je joue toujours vérifier pour éviter la situation quand uintsList est nul ou vide

EDIT 2 OK, le problème est résolu, j'ai changé le casting en utilisant la méthode ConvertAll, mais je ne comprends toujours pas comment cela peut arriver?
Donc cette question me dérange toujours: comment la même partie du code pourrait fonctionner correctement sur mon ordinateur, et jeter une exception à un autre? Différentes versions de compilateur/environnement? Certains paramètres spécifiques? Quelqu'un peut-il me dire où dois-je chercher les raisons de cette situation pour l'éviter à l'avenir?

+0

« Donc, cette question me tracasse encore: comment la même partie du code pourrait fonctionner correctement à mon ordinateur, et jeter une exception à un autre » Qu'est-ce qui fonctionne correctement sur un ordinateur et est problématique sur un autre? Si vous pensez que .ConvertAll (i => (double) i) 'se comporte comme' .Cast ', ce n'est pas vrai. Ce sont des choses fondamentalement différentes. '.ConvertAll' passe simplement chaque élément au délégué qui lui est passé et vous passez * manuellement * une fonction qui prend un' uint' et retourne un 'double' alors que' .Cast' essaie de faire le cast lui-même ce qui échoue pour le raison que j'ai mentionnée dans ma réponse. –

+0

Oui, je comprends cela et je vois où j'ai fait l'erreur. Mais la question est pourquoi l'erreur s'est produite?Pourquoi cela a fonctionné dans mon environnement (même si c'était faux) et a échoué (comme prévu) dans l'autre, comment attraper ce genre d'erreurs? – Gacek

+0

Peut-être que ça ne s'est pas vraiment passé :) Pouvez-vous le reproduire? Êtes-vous sûr de ne pas avoir comparé une version différente de votre binaire ou des choses de ce genre? –

Répondre

4

Voir: C# Converting List<int> to List<double>

Le casting uint ->double est valide, mais vous CASTING une liste de uints à une liste de doubles. Sur la plupart des architectures, les listes n'auront même pas la même taille (en octets) - vous devrez créer une liste entièrement nouvelle et lancer chaque élément individuellement. J'utiliser ConvertAll:

List<double> doublesList = uintsList.ConvertAll(x => (double)x); 
+4

"Sur la plupart des archétectures, les listes ne seront même pas de la même taille (en octets)" Ceci est totalement hors de propos. L'OP * ne lance pas * une "Liste " à "Liste ". Il appelle la méthode 'Enumerable.Cast' en passant une' Liste '. Il prend une séquence et essaie de lancer chaque ** élément individuel ** de la liste et génère une séquence de nouveau type. C'est totalement différent de lancer un 'List ' à 'List '. –

+0

'ConvertAll' fonctionne -> accepté. Je vous remercie! – Gacek

5

méthode .Cast ne vise pas à effectuer la conversion de type comme ça. Il effectue simplement des conversions dans la hiérarchie d'héritage.

La raison de ce comportement est que la signature de la méthode d'extension prend un IEnumerable et non IEnumerable<T>. Par conséquent, obtenir la propriété Current de l'énumérateur renvoie un object à la méthode Cast. Bien sûr, vous ne pouvez pas dégrouper directement un type de valeur d'un type vers un autre type. En gros, Cast fera quelque chose comme:

int i = 42; 
object o = i; 
double d = (double)o; // fails. 
Questions connexes