8
votes

Casting d'un dictionnaire générique contenant un dictionnaire générique

J'ai: xxx pré>

et je souhaite la jeter à une version d'interface, c'est-à-dire: p> xxx pré>

"Quelqu'unInterfaceStance" est un Propriété publique: P>

Unable to cast object of type 'System.Collections.Generic.Dictionary`2[System.String,System.Collections.Generic.Dictionary`2[System.String,System.Boolean]]' to type 'System.Collections.Generic.IDictionary`2[System.String,System.Collections.Generic.IDictionary`2[System.String,System.Boolean]]'.


4 commentaires

Vous ne pouvez pas modifier votre type d'origine intérieure-dictionnaire à ITHictionary <> ? Cela simplifierait les choses et cela ne nécessite généralement pas de gros changements dans le code qui remplit le dictionnaire.


@Digemall: Selon la réponse d'Eric, cela déplace simplement le problème, cela ne le résout pas.


Non, je demandais pourquoi ne faites-vous pas: var someconcreteInstance = nouveau dictionnaire > (); au lieu de votre ligne d'origine? Cela résoudrait le problème (vous n'aurez même pas besoin d'une distribution), mais bien sûr, vous pourriez avoir une raison de laisser votre code d'origine ...


Dupliqué possible de Identification In .NET 4 Pas Covariant


3 Réponses :


4
votes

2 commentaires

Oh, est-ce le problème! (Même dans .NET 4?) Avez-vous des suggestions sur la façon d'obtenir le résultat que je veux?


Dépend de ce que vous essayez de faire. Publiez une autre question sur ce que vous essayez d'atteindre et de demander le meilleur design.



1
votes

Le plus que vous puissiez faire est xxx

la raison que votre dictionnaire interne ne peut pas être référencé différemment ici (ou via une distribution) est que lorsque Dictionary est un code IMOITION , pas tous les objets Les objets seront Dictionnaire objets. En tant que tel, l'obtention d'une interface pure serait alors apparemment vous permettant d'ajouter d'autres > paires à la collection d'origine, lorsqu'il pourrait clairement y avoir des violations de type pour l'objet d'origine. . Par conséquent, cela n'est pas pris en charge.


0 commentaires

12
votes

Les autres réponses ont raison, mais juste pour être cristallins sur la raison pour laquelle cela est illégal, considérez les éléments suivants:

Dictionary<string, IAnimal> d3 = whatever;
d3["blake"] = new Tiger(); 
IDictionary<string, Giraffe> d4 = d3; // suppose this were legal
Giraffe g = d4["blake"]; // What stops this?


3 commentaires

Êtes-vous sûr que la dernière ligne est claire comme vous l'avez écrite? Mon code d'origine compile bien, mais jette une erreur d'exécution, le compilateur semble donc permettre de telles situations.


@ Nicodemus13: Votre code a un opérateur de distribution; le mien ne le fait pas. L'opérateur de distribution signifie «Prenez cette conversion qui aurait été illégale au moment de la compilation et le rendrait légal; s'il s'avère être illégal à l'exécution, lancez une exception». Et hé, devinez quoi? C'est ce qui se passe. Vous dites au compilateur "supposons que cette conversion illégale va fonctionner simplement", puis ce n'est pas le cas, et vous obtenez une exception. Le but d'un opérateur de distribution de type de référence consiste à déplacer le fardeau de la vérification du type du compilateur au runtime. Le fardeau ne disparaît pas, il se déplace juste.


"Girafe, girafe, brûlant brillant / dans les forêts de la nuit". Bonne chose que le système de type C # empêche de telles tragédies!