Pergunta

Eu tenho um bug muito estranho em nossa máquina de teste. O erro é:

System.TypeLoadException: Method 'SetShort' in type 'DummyItem' from assembly 'ActiveViewers (...)' does not have an implementation.

Eu só não consigo entender o porquê. SetShort existe na classe DummyItem, e eu mesmo recompilados uma versão com gravações para o log de eventos apenas para se certificar de que não é uma implantação / issue versionamento. O estranho é que o código de chamada nem sequer chamar o método SetShort.

Foi útil?

Solução

NOTA -. Se esta resposta não ajudá-lo, por favor, tome o tempo para percorrer as outras respostas que as pessoas têm adicionados desde

Resposta curta

Isso pode acontecer se você adicionar um método para uma interface em um único conjunto, e, em seguida, para uma classe de implementação em outra montagem, mas você reconstruir a implementação de montagem sem fazer referência a nova versão da interface de montagem.

Neste caso, DummyItem implementa uma interface de outro assembly. O método SetShort foi recentemente adicionado à interface e o DummyItem - mas o conjunto contendo DummyItem foi reconstruída referenciando a versão anterior da interface de montagem. Assim, o método SetShort é efetivamente lá, mas sem o molho mágico ligando-a ao método equivalente na interface.

Resposta longa

Se você quiser tentar reproduzir isso, tente o seguinte:

  1. Crie um projeto de biblioteca de classes: InterfaceDef, adicione apenas uma classe e construir:

    public interface IInterface
    {
        string GetString(string key);
        //short GetShort(string key);
    }
    
  2. Crie um segundo projeto de biblioteca de classe: Implementação (com solução separada), copie InterfaceDef.dll no diretório do projeto e adicionar como referência de arquivo, adicione apenas uma classe e construir:

    public class ImplementingClass : IInterface
    {
        #region IInterface Members
        public string GetString(string key)
        {
            return "hello world";
        }
    
        //public short GetShort(string key)
        //{
        //    return 1;
        //}
        #endregion
    }
    
  3. Crie uma terceira, projeto de console: ClientCode, copie os dois DLLs no diretório do projeto, adicionar referências de arquivo e adicione o seguinte código para o método principal:

     IInterface test = new ImplementingClass();
     string s = test.GetString("dummykey");
     Console.WriteLine(s);
     Console.ReadKey();
    
  4. Executar o código uma vez, o console diz "Olá mundo"

  5. Uncomment o código nos dois projetos DLL e reconstruir - copie os dois dlls de volta para o projeto ClientCode, reconstruir e tente executar novamente. TypeLoadException ocorre ao tentar instanciar o ImplementingClass.

Outras dicas

Além de que resposta do próprio autor da questão já foi dito, pode-se notar o seguinte. A razão isso acontece é porque é possível para uma classe para ter um método com a mesma assinatura como um método de interface sem implementar esse método. O código a seguir ilustra isso:

public interface IFoo
{
    void DoFoo();
}

public class Foo : IFoo
{
    public void DoFoo() { Console.WriteLine("This is _not_ the interface method."); }
    void IFoo.DoFoo() { Console.WriteLine("This _is_ the interface method."); }
}

Foo foo = new Foo();
foo.DoFoo();               // This calls the non-interface method
IFoo foo2 = foo;
foo2.DoFoo();              // This calls the interface method

Eu tenho esse quando meu aplicativo não tem uma referência a outro conjunto definindo uma classe que o método na mensagem de erro usado. Correndo PEVerify deu erro mais útil: "O sistema não pode encontrar o arquivo especificado"

me deparei com a mesma mensagem e aqui é o que nós encontramos: Usamos DLLs de terceiros em nosso projeto. Depois de uma nova libertação das pessoas estava fora mudamos nosso projeto para apontar para o novo conjunto de DLLs e compilado com sucesso.

A exceção foi lançada quando tentei um instatiate das suas aulas com interface durante o tempo de execução. Temos a certeza de que todas as outras referências foram até à data, mas ainda não sorte. Nós precisávamos de um tempo para detectar (usando o localizador de objectos) que o tipo de retorno do método na mensagem de erro era um tipo completamente novo de uma nova assembléia, não referenciado.

Nós adicionamos uma referência para a montagem e o erro desapareceu.

  • A mensagem de erro foi bastante enganosa, mas apontou mais ou menos para a direção certa (método certo, mensagem errada).
  • A exceção ocorreu mesmo que nós não usar o método em questão.
  • O que me leva à pergunta:? Se essa exceção é lançada, em qualquer caso, por que o compilador não pegá-lo

Recebi este erro no seguinte cenário.

  • ambas as montagens A e B referenciada System.Web.Mvc Versão 3.0.0.0
  • Assembleia A Assembleia referenciada B e tinha classes que implementadas as interfaces de montagem B com os métodos que retornou aulas de System.Web.Mvc.
  • Assembleia Um atualizado para System.Web.Mvc Versão 4.0.0.0
  • Assembleia C correu o código abaixo (FertPin.Classes.Contact foi contido em Assembly A):

var target = Assembly.GetAssembly(typeof(FertPin.Classes.Contact));

A correção para me foi atualizar a referência System.Web.Mvc na Assembléia B para 4.0.0.0. Parece óbvio agora!

Graças ao cartaz original!

A outra vez que você pode obter este erro é se você tiver uma versão incorreta de um assinado montagem. Não é o sintoma normal para esta causa, mas aqui foi o cenário onde eu entendi

  • um projeto asp.net contém assembly A e montagem B, B é fortemente nomeado

  • montagem A utiliza Activator.CreateInstance para carregar montagem C (isto é, não há nenhuma referência a C, que é construído em separado)

  • C foi construído fazendo referência a uma versão mais antiga do conjunto B do que é actualmente presentes

esperança de que ajude alguém -. Levei séculos para descobrir isso

Eu tive esse erro também, ele foi causado por um assembléias Qualquer CPU exe referência Qualquer CPU que, por sua vez referenciados um x86 montagem.

A exceção reclamou de um método em uma classe em MyApp.Implementations (qualquer CPU), que derivados MyApp.Interfaces (qualquer CPU), mas em Fuslogvw.exe eu encontrei uma 'tentativa de carregar o programa com um formato incorreto' escondido excepção de MyApp.CommonTypes (x 86), o qual é utilizado por ambos.

Eu continuar a voltar a esta ... Muitas das respostas aqui fazer um grande trabalho de explicar qual é o problema, mas não como corrigi-lo.

A solução para isso é para excluir manualmente os arquivos bin em seus projetos diretório publicados. Ele irá limpar todas as referências e forçar o projeto para usar as últimas DLLs.

Eu não sugiro usar as ferramentas publicar função Excluir, porque isso tende a jogar fora IIS.

Ainda tenho outra solução esotérica para esta mensagem de erro. Eu atualizei meu estrutura de destino do .NET 4.0 a 4.6, e meu projeto de teste de unidade estava me dando o "System.TypeLoadException ... não tem uma implementação" erro quando eu tentei construir. Ele também deu uma segunda mensagem de erro sobre o mesmo método supostamente não-implementado, que disse: "A tarefa 'BuildShadowTask' falhou inesperadamente." Nenhum dos conselhos aqui parecia ajuda, então eu procurei por "BuildShadowTask", e encontrou um post no MSDN que me levou a usar um editor de texto para excluir essas linhas de arquivo csproj do projeto de teste de unidade.

<ItemGroup>
  <Shadow Include="Test References\MyProject.accessor" />
</ItemGroup>

Depois disso, ambos os erros foi embora e o projeto construído.

Eu encontrei este erro em um contexto onde eu estava usando Autofac e um monte de carregamento conjunto dinâmico.

Durante a execução de uma operação de resolução Autofac, o tempo de execução não seria suficiente para carregar um dos conjuntos. A mensagem de erro se queixou de que Method 'MyMethod' in type 'MyType' from assembly 'ImplementationAssembly' does not have an implementation. Os sintomas ocorreu quando rodando em um R2 VM Windows Server 2012, mas fez não ocorre no Windows 10 ou Windows Server 2016 VMs.

ImplementationAssembly referenciado System.Collections.Immutable 1.1.37, e implementações contidos de uma interface IMyInterface<T1,T2>, o qual foi definido em uma DefinitionAssembly separado. DefinitionAssembly referenciada System.Collections.Immutable 1.1.36.

Os métodos de IMyInterface<T1,T2> que foram "não implementado" tinha parâmetros do tipo IImmutableDictionary<TKey, TRow>, que é definido em System.Collections.Immutable.

A cópia real de System.Collections.Immutable encontrado no diretório do programa foi a versão 1.1.37. No meu Windows Server 2012 R2 VM, o GAC continha uma cópia do System.Collections.Immutable 1.1.36. No Windows 10 e Windows Server 2016, o GAC continha uma cópia do System.Collections.Immutable 1.1.37. O erro de carregamento ocorreu somente quando o GAC continha a versão mais antiga do DLL.

Assim, a causa raiz da falha de carga de montagem foi as referências descasamento para System.Collections.Immutable. A definição de interface e implementação teve assinaturas de métodos idênticos de aparência, mas na verdade dependia de diferentes versões do System.Collections.Immutable, o que significava que o tempo de execução não considera a classe de implementação para corresponder à definição de interface.

Adicionando o redirecionamento seguinte ligação para meu arquivo de configuração aplicativo corrigido o problema:

<dependentAssembly>
        <assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-1.1.37.0" newVersion="1.1.37.0" />
</dependentAssembly>

Eu tenho isso com um "diamante" dependência do projeto em forma:

  • Projeto Um usa Projeto B e Projeto D
  • Projeto B usa Projeto D

Eu recompilados projeto A, mas não Projeto B, o que permitiu Projeto B "inserir" a versão antiga do Projeto D dll

Eu encontrei isso quando eu renomeado um projeto (e o nome do assembly), que foi dependia de um projeto ASP.NET. Tipos no projeto web implementado interfaces no assembly dependente. Apesar execução Limpo Solution no menu Build, a montagem com o nome anterior permaneceu na pasta bin, e quando o meu projeto web executado

var types = AppDomain.CurrentDomain.
   GetAssemblies().
   ToList().
   SelectMany( s => s.GetTypes() /* exception thrown in this call */ )
;

a exceção acima foi lançada, queixando-se que os métodos de interface nos tipos web de execução não foram efetivamente implementadas. Manualmente excluir o conjunto na pasta bin do projeto web resolveu o problema.

Eu também tenho esse erro quando eu já havia habilitado cobertura de código durante o teste de unidade para um dos conjuntos. Por alguma razão Visual Studio "tampão" a antiga versão deste DLL em particular mesmo que eu tinha atualizado para implementar uma nova versão da interface. Desativando cobertura de código se livrou do erro.

Outra explicação para este tipo de problema envolvendo gerenciado C ++.

Se você tentar stub uma interface definida em uma montagem criada usando gerenciado C ++ que tem uma assinatura especial que você vai obter a exceção quando o stub é criado.

Isto é verdade para Rhino Mocks e provavelmente qualquer plataforma de simulacros que usos System.Reflection.Emit.

public interface class IFoo {
  void F(long bar);
};

public ref class Foo : public IFoo {
public:
  virtual void F(long bar) { ... }
};

A definição de interface recebe a seguinte assinatura:

void F(System.Int32 modopt(IsLong) bar)

Note que o tipo C ++ long mapeia para System.Int32 (ou simplesmente int em C #). É o modopt um tanto obscuro que está causando o problema como afirma Ayende Rahien em a lista de discussão Rhino Mocks .

Este erro também pode ser causado se um conjunto é carregado usando assembly.LoadFrom (String) e faz referência a uma montagem que já foi carregado usando Assembly.Load (Byte []).

Por exemplo, você tem incorporado assemblies referenciados a principal do aplicativo como recursos, mas suas cargas de aplicativos plug-ins a partir de uma pasta específica.

Em vez de usar LoadFrom você deve usar Load. O código a seguir irá fazer o trabalho:

private static Assembly LoadAssemblyFromFile( String filePath )
{
    using( Stream stream = File.OpenRead( filePath ) )
    {
        if( !ReferenceEquals( stream, null ) )
        {
            Byte[] assemblyData = new Byte[stream.Length];
            stream.Read( assemblyData, 0, assemblyData.Length );
            return Assembly.Load( assemblyData );
        }
    }
    return null;
}

Eu acabei de atualizar uma solução de MVC3 para MVC5, e começou a receber a mesma exceção do meu projeto de teste unitário.

verificado todas as referências à procura de arquivos antigos, eventualy descobriu que precisava fazer algumas bindingRedirects para MVC, no meu projeto de teste de unidade.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="0.0.0.0-5.1.0.0" newVersion="5.1.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

No meu caso, ajudou a redefinir o WinForms Toolbox.

Eu tenho a exceção ao abrir um Form no designer; no entanto, compilar e executar o código era possível e o código se comportou como esperado. A exceção ocorreu em um UserControl locais implementação de uma interface de uma das minhas bibliotecas de referência. O erro surgiu após esta biblioteca foi atualizado.

Esta UserControl foi listado no WinForms Toolbox. Provavelmente Visual Studio manteve uma referência em uma versão desactualizada da biblioteca ou se o cache de uma versão em algum lugar desatualizado.

Aqui está como eu recuperou dessa situação:

  1. clique direito sobre o WinForms Toolbox e clique em Reset Toolbox no menu de contexto. (Este itens remove personalizadas do Toolbox).
    No meu caso os itens de caixa de ferramentas foram restaurados ao seu estado padrão; No entanto, o ponteiro de seta estava faltando na caixa de ferramentas.
  2. Feche o Visual Studio.
    No meu caso Visual Studio encerrado com uma exceção de violação e abortada.
  3. Reinicie o Visual Studio.
    Agora tudo está funcionando perfeitamente.

FWIW, eu tenho isso quando havia um arquivo de configuração que redirecionado para uma versão não-existente de uma referência de montagem. toras de fusão para a vitória!

Eu tenho esse erro, porque eu tinha uma classe em uma montagem 'C', que foi na versão 4.5 do framework, implementar uma interface em assembly 'A' que estava em versão 4.5.1 do quadro e servir como a base classe para assembly 'B', que também estava na versão 4.5.1 do quadro. O sistema gerou a exceção ao tentar carregar assembly 'B'. Além disso, eu tinha instalado alguns pacotes NuGet visando .net 4.5.1 em todos os três conjuntos. Por alguma razão, embora as referências NuGet não estavam mostrando em assembly 'B', ele estava construindo com sucesso.

Descobriu-se que a verdadeira questão era que as igrejas eram referência a diferentes versões de um pacote NuGet que continha a interface e a assinatura de interface mudou entre as versões.

No meu caso eu tinha mencionado anteriormente um projeto mylib em um fora pasta irmão do repo - o chamado de deixar isso v1.0.

|-- myrepo
|    |-- consoleApp
|    |-- submodules
|         |-- mylib (submoduled v2.0)
|-- mylib (stale v1.0)

Mais tarde eu fiz-lo corretamente e usou-o através de um submódulo git - permite chamadas que v2.0. Um consoleApp projeto, contudo, não foi atualizado corretamente. Ele ainda estava se referindo a velha fora de projeto v1.0 do meu projeto git.

Desconcertante , mesmo que o *.csproj foi claramente errado e apontando para v1.0, o Visual Studio IDE mostrou o caminho que o projeto v2.0! F12 para inspecionar a interface e classe foi para a versão v2.0 também.

O conjunto colocado na pasta bin pelo compilador foi a versão v1.0, consequentemente, a dor de cabeça.

O fato de que o IDE estava mentindo para mim tornou extra difícil perceber o erro.

Solução :. Referências do projeto excluído do ConsoleApp e lidos-los

Dica geral: Recompile todos os conjuntos a partir do zero (sempre que possível, não posso para pacotes NuGet é claro) e verificar data e hora carimbos em pasta bin\debug. Quaisquer antigas montagens datados são o seu problema.

Eu enfrentei quase o mesmo assunto. Eu estava coçando minha cabeça o que está causando esse erro. Cruzei marcada, foram implementados todos os métodos.

Em Googling eu tenho essa ligação entre outros. Baseado no comentário @ Paulo McLink, Estas duas etapas resolverem o problema.

  1. Reiniciar Visual Studio
  2. Limpo, Construir (Reconstruir)

e Erro ido .

Restart VS Plugin

Graças Paul:)

Espero que isso ajude alguém que se deparar com este erro:)

Eu também corri para este problema durante a execução de meus UnitTests. A multa correu aplicação e sem erros. A causa do problema no meu caso era que eu tinha desligado a construção dos projetos de teste. Reativando a construção de meus testprojects resolvido os problemas.

Eu vi isso no Visual Pro 2008 Estúdio quando dois projectos conjuntos construídos com o mesmo nome, um de uma classe lib SDF.dll, e que referenciou o lib com o nome de montagem sdf.exe. Quando eu mudei o nome da referência de montagem, a exceção foi embora

Isto significa simplesmente que o projeto de implementação está desatualizado em meus casos. A DLL que contém a interface foi reconstruída, mas a dll implementação foi envelhecer.

Aqui está a minha opinião sobre este erro.

Adicionado um método extern, mas a minha pasta estava com defeito. O DllImportAttribute tem colocado em uma linha comentada.

/// <returns>(removed for brevity lol)</returns>[DllImport("user32.dll")] 
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool IsWindowVisible(IntPtr hWnd);

garante que o atributo foi realmente incluído na fonte corrigiu o problema.

Eu tenho isso em um serviço WCF devido a ter um tipo x86 compilação selecionada, fazendo com que as caixas de viver sob bin \ x86 em vez de bin. A seleção de qualquer CPU causou as DLLs recompilados para ir para os locais corretos (Eu não vou entrar em detalhes de como isso aconteceu, em primeiro lugar).

Eu tive o mesmo problema. Eu descobri que a minha montagem, que é carregado pelo programa principal, tinha algumas referências com "Copy Local" definido como verdadeiro. Estas cópias locais de referências procurando outras referências na mesma pasta, que não existiam porque o "Copy Local" de outras referências foi definida como falsa. Após a supressão das referências "acidentalmente" copiados o erro se foi porque o programa principal foi criado para procurar locais corretos de referências. Aparentemente, as cópias locais das referências asneira a seqüência de chamar porque estas cópias locais foram usados ??em vez dos originais presentes no programa principal.

A mensagem para levar para casa é que este erro aparece devido ao elo que faltava para carregar o necessário montagem.

No meu caso, eu estava tentando usar TypeBuilder para criar um tipo. TypeBuilder.CreateType jogou esta exceção. Eu finalmente percebi que eu precisava para adicionar MethodAttributes.Virtual aos atributos ao chamar TypeBuilder.DefineMethod para um método que ajuda implementa uma interface. Isso ocorre porque, sem esse sinalizador, o método não implementa a interface, mas sim um novo método com a mesma assinatura em vez (mesmo sem especificar MethodAttributes.NewSlot).

Como um adendo: isso também pode ocorrer se você atualizar um pacote NuGet que foi usado para gerar um falsificações montagem. Digamos que você instalar V1.0 de um pacote NuGet e criar um falsificações montagem "fakeLibrary.1.0.0.0.Fakes". Em seguida, você atualizar para a versão mais recente do pacote NuGet, dizem v1.1 que acrescentou um novo método para uma interface. A biblioteca Fakes ainda está procurando v1.0 da biblioteca. Basta remover a falsa montagem e regenerá-lo. Se fosse esse o problema, isto irá provavelmente corrigi-lo.

Recebi esse erro depois de um windows update recente. Eu tinha um conjunto de classe de serviço para herdar de uma interface. A interface continha uma assinatura que retornou um ValueTuple, um bastante novo recurso no C #.

Tudo que eu posso adivinhar é que a atualização do Windows instalado um novo, mas mesmo explicitamente referência a ele, atualizando redirecionamentos de ligação, etc ... O resultado final foi apenas mudando a assinatura do método para algo "standard" Eu acho que você poderia dizer.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top