2008-09-23 11 views
3

J'ai une application ASP.NET en cours d'exécution sur un serveur web distant et je viens de commencer à obtenir cette erreur:compilateur C# Optimise de manière incorrecte code

Method not found: 'Void System.Collections.Generic.ICollection`1..ctor()'. 

Je démonte le code dans la DLL et il semble que le compilateur est optimiser de manière incorrecte le code. (Notez que Set est une classe qui implémente un ensemble d'objets uniques Il hérite de IEnumerable..) Cette ligne:

Set<int> set = new Set<int>(); 

est compilé dans cette ligne:

Set<int> set = (Set<int>) new ICollection<CalendarModule>(); 

La classe CalendarModule est totalement classe sans rapport !! Est-ce que quelqu'un a déjà remarqué .NET compiler incorrectement du code comme ça avant?

Mise à jour # 1: Ce problème semble être introduit par l'outil ILMerge de Microsoft. Nous étudions actuellement comment le surmonter.

Mise à jour # 2: Nous avons trouvé deux façons de résoudre ce problème jusqu'à présent. Nous ne comprenons pas très bien le problème sous-jacent, mais les deux le corrigent:

  1. Désactivez l'optimisation.

  2. Fusionnez l'assembly avec ILMerge sur un autre ordinateur.

Alors on se demande si la machine de construction est en quelque sorte une erreur de configuration (ce qui est étrange étant donné que nous avons utilisé la machine à construire des versions pour plus d'un an) ou si elle est un autre problème. Etes-vous sûr que l'assemblage que vous regardez a été généré à partir du code source en question?

+0

Ce code est insuffisant pour déboguer votre problème. Pourriez-vous télécharger suffisamment de code pour reproduire le problème quelque part? – Wedge

+2

Vous ne savez pas que Int hérite de CalenderModule? :) – FlySwat

Répondre

7

Ahh, ILMerge - cette information supplémentaire dans votre question aide vraiment votre problème. Bien que je ne m'attendrais jamais à ce que le compilateur .net échoue de cette manière, je m'attendrais à voir de temps en temps ce genre de choses avec ILMerge (vu ce qu'il fait). Je pense que deux de vos assemblages utilisent le même «truc» d'optimisation, et une fois fusionné, vous obtenez le conflit.

Avez-vous soulevé le problème avec Microsoft?

Une solution de contournement est entre-temps de recompiler les assemblages à partir de la source en un seul assemblage, ce qui évite le besoin de ILMerge. Comme les fichiers csproj ne sont que des listes XML, ils sont faciles à fusionner, et vous pouvez automatiser cela en tant qu'étape MSBuild supplémentaire.

+0

La fusion des fichiers .csproj est une bonne idée, nous pourrions essayer cela. –

+0

Est-ce que quelqu'un a de bonnes ressources sur la façon de compiler plusieurs assemblées en une seule en utilisant le compilateur cs/vb sans ILMerge? – Lamar

+0

@Lamar: J'ai déjà répondu à cette question avant. Voir http://stackoverflow.com/questions/1878807/vs2008-creating-single-dll-from-solution-with-many-projects/1879281#1879281 –

1

Êtes-vous capable de reproduire ce problème avec un petit cas de test? Si vous utilisez Reflector, il est possible que la conversion MSIL vers C# ne soit pas correcte - Le réflecteur n'est pas toujours précis à 100% lors de la décompilation. À quoi ressemble le MSIL? Hmm ... Je viens de me rendre compte qu'il ne peut pas être un réflecteur en faute ou que vous n'auriez pas reçu ce message d'erreur au moment de l'exécution.

+0

J'ai été incapable de reproduire le problème avec un cas de test plus petit jusqu'à présent. Dans ce cas, le démontage semble être correct. Ceci est mis en évidence par l'erreur que je me réfère au constructeur ICollection. –

+0

Est-ce que la compilation sans optimisations se débarrasse de l'erreur? –

0

Le code a-t-il été récemment déployé sur ce serveur? Quelqu'un aurait-il pu pousser une construction à votre insu? Pouvez-vous aller au contrôle de la source, tirer le dernier, et dupliquer le problème?

À ce stade, avec les informations données, je doute que ce soit le compilateur.

1

Ceci est plus susceptible d'être un problème avec l'outil de réflexion qu'avec la compilation .Net. L'erreur que vous obtenez - un constructeur introuvable lors de l'accès distant est le plus susceptible d'être un problème de sérialisation (toutes les classes sérialisables nécessitent un constructeur sans paramètre).

Le code trouvé dans votre outil de réflexion est plus susceptible de générer une exception de type de publication.

+0

Il n'y a pas de sérialisation dans le code. –

+0

Ok, mais le jet d'exception nécessiterait le code suivant: new ICollection () – Keith

1

Je suis d'accord avec Curt et Beds; Cela ressemble à quelque chose qui ne va vraiment pas.L'optimiseur a fonctionné pour nous tous et aucun de ces bogues n'ont été rapportés (que je sache) - pourrait-il être que vous faites, en fait, quelque chose de mal?

Sidenote: Je voudrais également signaler System.Collections.Generic.HashSet<T> qui est en .Net fx 3.5 et fait exactement ce qu'une classe Set<> devrait.

+0

Je suis définitivement d'accord avec l'école de pensée "select is not broken", et l'erreur n'est probablement pas causée par un mauvais compilateur, juste quelque chose qui ressemble à une mauvaise optimisation. Merci pour le conseil sur HashSet , malheureusement, nous ne sommes pas encore sur 3.5, toujours sur 2.0. –

0

Ouch. Si c'est vraiment ILMerge en faute, s'il vous plaît gardez cette rubrique à jour avec vos résultats - J'utilise ILMerge comme une étape clé dans la construction d'un assemblage d'interopérabilité COM.

+0

Je vais vous faire savoir ce que nous trouvons. –

Questions connexes