41 votes

L'opération pourrait déstabiliser l'exécution?

Je vais avoir un peu de mal à comprendre quel est le problème ici. J'ai un peu de code qui tire des enregistrements d'une base de données en utilisant LINQ et les met dans un objet qui est jeté dans une interface. Il ressemble un peu à ceci:

public IEnumerable<ISomeObject> query()
{
    return from a in dc.SomeTable
           select new SomeObject
           {
             //Assign various members here
           } as ISomeObject;
}

Quand j'ai tester, j'ai mis de l'interface IEnumerable retournée dans une variable appelée les résultats et de les exécuter cette ligne:

Assert.AreEqual(EXPECTED_COUNT, results.Count());

Lorsque cela est géré, je reçois un Système.De sécurité.VerificationException: "l'Opération pourrait déstabiliser le moteur d'exécution."

J'ai trouvé la solution ici, qui est-ce:

var results = from a in dc.SomeTable
              select new SomeObject
              {
                //Assign various members here
              } as ISomeTable;
return results.OfType<ISomeObject>();

Cela fonctionne, mais je vais avoir du mal à comprendre ce qui se passe ici. Pourquoi ai-je l'exception, en premier lieu, et comment les lignes de code ci-dessus résoudre ce problème? La documentation MSDN semble suggérer que c'est une question de sécurité de type, mais je ne vois pas où le code précédent était de type dangereux.

Mise à JOUR Un peu plus d'information j'ai trouvé. Le premier exemple fonctionne si je fais le type de retour IQueryable. Cela met un peu plus de lumière sur ce qui n'allait pas, mais je suis toujours confus au sujet de la pourquoi. Pourquoi ne pas le compilateur me forcer à lancer l'interface IEnumerable dans un IQueryable?

19voto

Grant Wagner Points 14085

Je crois que c'est un problème de covariance ou de contravariance comme indiqué par ce post sur le forum.

Voir la Covariance et la Contravariance en C#, deuxième Partie: de la Matrice de Covariance et le reste de la Covariance et la Contravariance série à Eric Lippert blog.

Bien qu'il est en relation avec les Tableaux dans l'article que j'ai lié, je crois, un problème similaire se présente ici. Avec votre premier exemple, vous retournez un IEnumerable qui peut contenir des objets qui implémentent une interface qui est plus grand que ISomeTable (c'est à dire - vous pourriez mettre une Tortue dans un Animaux IEnumerable lorsque que IEnumerable ne peut contenir que des Girafes). Je pense que la raison pour laquelle il fonctionne lorsque vous revenez IQueryable est parce que c'est plus grand/plus vaste que tout ce que vous pourriez revenir, alors vous avez la garantie que ce que vous revenez, vous serez en mesure de gérer(?).

Dans le deuxième exemple, OfType est de s'assurer que ce qui est retourné est un objet qui stocke toutes les informations nécessaires pour renvoyer uniquement les éléments qui peuvent être exprimées à la Girafe.

Je suis assez sûr qu'il a quelque chose à voir avec les questions de sécurité du type décrit ci-dessus, mais comme Eric Lippert dit des Fonctions d'Ordre Supérieur Mal à Mon Cerveau et je vais avoir de la difficulté à exprimer précisément pourquoi c'est un co/contravariant question.

15voto

Ira Miller Points 199

J'ai trouvé cette entrée alors que la recherche de ma propre solution à "l'opération pourrait déstabiliser le moteur d'exécution". Alors que la covariance/contra-variance des conseils ci-dessus a l'air très intéressant, en fin de compte j'ai trouvé que je reçois le même message d'erreur en exécutant mes tests unitaires avec la couverture de code en marche, et l'AllowPartiallyTrustedCallers assemblée attribut.

Suppression de l'attribut AllowPartiallyTrustedCallers causé mes essais pour fonctionner correctement. Je pourrais également désactiver la couverture de code pour le faire fuir, mais ce n'était pas une solution acceptable.

Espérons que cela aide quelqu'un d'autre qui le fait à cette page en essayant de trouver une solution à ce problème.

6voto

Zachary Yates Points 4952

Juste une supposition, mais la comme opérateur peut retourner null - de sorte qu'il peut avoir à faire avec la mise en œuvre effective de l' new SomeObject { ... } code, puisque c'est sucre syntaxique. L' return results.OfType<ISomeTable>(); filtres basés sur le type, de sorte que votre retour de la méthode de déclaration ne revenir que le type (en veillant à ce type de sécurité). J'ai couru dans un problème similaire avec le retour des types génériques.

P. S. j'aime "Opération pourrait déstabiliser le moteur d'exécution." l'exception". C'est presque comme si le "Vous risquez de faire exploser l'internet" l'exception".

2voto

Red Taz Points 1201

Je suis tombé sur cette erreur avec le même code;

IEnumerable<Table> records = (from t in db.Tables
                              where t.Id.Equals(1)
                              select t).ToList();

Cette apparemment inoffensif de code fait partie d'un UserControl méthode qui a été appelé à partir d'une Page. Pas de problème dans une .NET4 environnement de développement, cependant, lorsque le site a été Précompilés et déployé sur le serveur .NET3.5 j'ai eu cette erreur.

Je soupçonne que cela a quelque chose à voir avec le fait que le contrôle a été compilés dans une DLL combiné avec les modifications de sécurité entre les cadres comme décrit dans le présent .NET blog sur la sécurité

Ma solution: exécutez le site en direct sur .NET4

0voto

Av Pinzur Points 1130

Faut-il encore échouer si vous modifiez ce qui suit:

select new SomeObject { ... } as ISomeTable;

pour cela:

select (ISomeTable) new SomeObject { ... };

?

Si (comme je vois que vous avez confirmé), peut-être que cela a à voir avec le fait que l'implémentation de l'interface peut être soit une classe ou d'une structure? Le problème est-il toujours d'apparaître si vous en fonte pour une classe abstraite plutôt qu'une interface?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X