Question

J'ai une application ASP.NET s'exécutant sur un serveur Web distant et je viens juste de commencer à recevoir l'erreur suivante:

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

J'ai désassemblé le code dans la DLL et il semble que le compilateur optimise incorrectement le code. (Notez que Set est une classe qui implémente un ensemble d'objets uniques. Elle 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 une classe totalement indépendante !! Quelqu'un a-t-il déjà remarqué que .NET compilait un code incorrect comme celui-ci auparavant?

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

Mise à jour n ° 2: Nous avons trouvé deux moyens de résoudre ce problème jusqu'à présent. Nous ne comprenons pas très bien le problème sous-jacent, mais ces deux problèmes sont corrigés:

  1. Désactivez l'optimisation.

  2. Fusionnez l'assembly avec ILMerge sur une autre machine.

Nous nous demandons donc si la machine de compilation est mal configurée (ce qui est étrange si l’on utilise la machine pour compiler des versions depuis plus d’un an) ou s’il s’agit d’un autre problème.

Était-ce utile?

La solution

Ahh, ILMerge - cette information supplémentaire dans votre question aide vraiment à résoudre votre problème. Bien que je ne m'attende pas à ce que le compilateur .net échoue de cette manière, je m'attendrais parfois à voir ce genre de chose avec ILMerge (compte tenu de ce qu'il fait).

Je suppose que deux de vos assemblages utilisent le même "truc" d'optimisation et qu'une fois fusionnés, vous obtenez le conflit.

Avez-vous soulevé le bogue avec Microsoft?

Une solution de contournement consiste à recompiler les assemblages à partir de la source en un seul assemblage, en évitant la nécessité d’ILMerge. Comme les fichiers csproj ne sont que des listes XML, ils sont en principe faciles à fusionner et vous pouvez les automatiser en une étape supplémentaire de MSBuild.

Autres conseils

Êtes-vous sûr que l'assembly que vous regardez a été généré à partir du code source en question? Pouvez-vous reproduire ce problème avec un petit cas de test?

Modifier: si vous utilisez Reflector, il est possible que la conversion de MSIL en C # ne soit pas correcte. Reflector n’a pas toujours une précision de 100% lors de la décompilation. À quoi ressemble le MSIL?

Modifier 2: Hmm ... Je viens de me rendre compte que ce ne peut pas être Reflector qui est en faute, sinon vous n'auriez pas reçu ce message d'erreur au moment de l'exécution.

C’est plus probablement un problème avec l’outil de réflexion que avec la compilation .Net. L'erreur que vous obtenez - un constructeur non trouvé pendant la communication à distance est probablement un problème de sérialisation (toutes les classes sérialisables ont besoin d'un constructeur sans paramètre).

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

Je suis d’accord avec Curt et Beds; cela ressemble à quelque chose qui cloche sérieusement. L’optimiseur a fonctionné pour nous tous et aucun de ces bogues n’a été signalé (à ma connaissance) - est-il possible que vous fassiez quelque chose de mal?

Sidenote: J'aimerais également souligner System.Collections.Generic.HashSet<T> qui se trouve dans .Net fx 3.5 et fait exactement ce qu'une classe Set<> devrait.

.

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 accéder au contrôle de source, extraire la dernière et dupliquer le problème?

À ce stade, avec les informations fournies, je doute que ce soit le compilateur.

Aïe. Si c'est vraiment ILMerge qui est en cause, gardez ce sujet à jour avec vos conclusions. J'utilise ILMerge comme une étape clé dans la construction d'un assemblage d'interopérabilité COM.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top