C # Compiler incorretamente Otimiza Código
-
02-07-2019 - |
Pergunta
Tenho uma aplicação ASP.NET executado em um servidor web remoto e eu só comecei a receber este erro:
Method not found: 'Void System.Collections.Generic.ICollection`1..ctor()'.
Eu desmontado o código na DLL e parece que o compilador é incorretamente otimizar o código. (Note-se que Set é uma classe que implementa um conjunto de objetos únicos Ele herda de IEnumerable..) Esta linha:
Set<int> set = new Set<int>();
é compilado em esta linha:
Set<int> set = (Set<int>) new ICollection<CalendarModule>();
A classe CalendarModule é uma classe totalmente diferente !! Alguém já reparou .NET incorretamente compilar o código como este antes?
Atualizar # 1: Este problema parece ser introduzida por "noreferrer nofollow" Microsoft de ferramenta ILMerge . Estamos investigando como superá-lo.
Atualização # 2: Nós encontramos duas maneiras de resolver este problema até agora. Nós não entendo muito bem o que o problema subjacente é, mas ambos corrigi-lo:
-
Desligue otimização.
-
Mesclar a assemblie com ILMerge em uma máquina diferente.
Então, ficamos imaginando se a máquina de compilação está configurado incorretamente de alguma forma (o que é estranho, considerando que temos vindo a utilizar a máquina para lançamentos compilação para mais de um ano) ou se é algum outro problema.
Solução
Ahh, ILMerge - que informações adicionais na sua pergunta realmente ajuda com seu problema. Enquanto eu não iria nunca esperar que o compilador .net a falhar desta forma que seria de esperar para ver, ocasionalmente, este tipo de coisa com ILMerge (dado o que está fazendo).
Meu palpite é que duas das suas montagens estão usando a mesma otimização 'truque', e uma vez que se fundiu você começa o conflito.
Você já levantou o bug com Microsoft?
Uma solução alternativa, entretanto, é recompilar os conjuntos de fonte como uma única montagem, evitando a necessidade para ILMerge. Como os arquivos csproj são apenas listas XML eles são basicamente fácil de merge, e você poderia automatizar isso como um passo MSBuild extra.
Outras dicas
Você tem certeza de que o conjunto que você está olhando realmente foi gerado a partir do código-fonte em questão? Você é capaz de reproduzir este problema com um caso de teste pequena?
Editar: se você estiver usando reflector, é possível que o MSIL para C # conversão não é correto - Refletor nem sempre é 100% exato em Decompiling. Como é o MSIL como?
Editar. 2: Hmm ... Eu só percebi que ele não pode ser refletor em falta ou você não teria conseguido essa mensagem de erro em tempo de execução
Esta é mais provável que seja um problema com a ferramenta de reflexão do que com a compilação .Net. O erro que você está recebendo - um construtor não encontrado durante a comunicação remota é mais provável de ser um problema de serialização (todas as classes serialisable precisa de um construtor sem parâmetros)
.O código encontrado a partir de sua reflexão ferramenta é mais propensos a lançar uma exceção typecast.
Concordo com ambos Curt e camas; Isso soa como algo está seriamente errado. O otimizador tem trabalhado para todos nós, nem tais erros foram relatados (que eu saiba) - será que você é, de fato, fazendo algo errado
? Sidenote: Eu também gostaria de salientar System.Collections.Generic.HashSet<T>
que está em .Net fx 3.5 e faz exatamente o que uma classe Set<>
deve
Foi código recentemente implantado para esse servidor? alguém poderia ter empurrado uma compilação sem o seu conhecimento? você pode ir para o controle de origem, puxe o mais tardar, e duplicar o problema?
Neste ponto, com a informação dada, eu duvido que é o compilador.
Ouch. Se isso realmente é ILMerge a culpa, por favor, mantenha este tema up-to-date com as suas descobertas -. Eu uso ILMerge como um passo fundamental na construção de uma interoperabilidade COM montagem