TypeLoadException говорит «нет реализации», но оно реализовано - PullRequest
255 голосов
/ 04 июня 2009

У меня очень странная ошибка на нашей тестовой машине. Ошибка:

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

Я просто не могу понять, почему. SetShort есть в классе DummyItem, и я даже перекомпилировал версию с записью в журнал событий, просто чтобы убедиться, что это не проблема развертывания / управления версиями. Странно то, что вызывающий код даже не вызывает метод SetShort.

Ответы [ 37 ]

5 голосов
/ 23 сентября 2010

Я получил это с зависимостью проекта в форме «ромба»:

  • Проект A использует Проект B и Проект D
  • Проект B использует Проект D

Я перекомпилировал проект A, но не проект B, что позволило проекту B «внедрить» старую версию проекта D dll

5 голосов
/ 27 мая 2012

Я столкнулся с этим, когда переименовал проект (и имя сборки), от которого зависел проект ASP.NET. Типы в веб-проекте реализованы интерфейсами в зависимой сборке. Несмотря на выполнение Clean Solution из меню Build, сборка с предыдущим именем осталась в папке bin, и когда мой веб-проект выполнил

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

Вышеприведенное исключение было выдвинуто с жалобой на то, что методы интерфейса в реализующих веб-типах фактически не были реализованы. Удаление сборки в папке bin веб-проекта вручную решило проблему.

4 голосов
/ 26 сентября 2010

Я также получил эту ошибку, когда ранее включил покрытие кода во время модульного тестирования для одной из сборок. По какой-то причине Visual Studio "буферизовала" старую версию этой конкретной DLL, хотя я обновил ее, чтобы реализовать новую версию интерфейса. Отключение покрытия кода избавило от ошибки.

3 голосов
/ 11 ноября 2011

Эта ошибка также может возникать, если сборка загружается с использованием Assembly.LoadFrom (String) и ссылается на сборку, которая уже была загружена с использованием Assembly.Load (Byte []).

Например, вы встраивали ссылочные сборки основного приложения в качестве ресурсов, но ваше приложение загружает плагины из определенной папки.

Вместо LoadFrom вы должны использовать Load. Следующий код сделает работу:

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;
}
3 голосов
/ 12 мая 2011

Другое объяснение проблемы такого типа, связанной с управляемым C ++.

Если вы попытаетесь заглушить интерфейс, определенный в сборке, созданной с использованием управляемого C ++, которая имеет специальную подпись, вы получите исключение при создании заглушки.

Это верно для Rhino Mocks и, вероятно, для любой фальшивой среды, которая использует System.Reflection.Emit.

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

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

Определение интерфейса получает следующую подпись:

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

Обратите внимание, что тип C ++ long отображается на System.Int32 (или просто int в C #). Это неясная проблема modopt вызывает проблему , как заявлено Айенде Рахиен в списке рассылки Rhino Mocks .

3 голосов
/ 25 марта 2014

Я только что обновил решение с MVC3 до MVC5 и начал получать то же исключение из моего проекта модульного тестирования.

Проверил все ссылки, ища старые файлы, в конце концов обнаружил, что мне нужно было выполнить несколько bindingRedirects для Mvc, в моем проекте модульного тестирования.

<?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>
3 голосов
/ 10 декабря 2009

FWIW, я получил это, когда был файл конфигурации, перенаправленный на несуществующую версию ссылочной сборки. Логи Fusion для победы!

3 голосов
/ 17 сентября 2014

В моем случае это помогло сбросить WinForms Toolbox.

Я получил исключение при открытии Form в конструкторе; однако компиляция и запуск кода были возможны, и код вел себя как ожидалось. Исключение произошло в локальной UserControl, реализующей интерфейс из одной из моих библиотек Ошибка возникла после обновления этой библиотеки.

Этот UserControl был указан в наборе инструментов WinForms. Возможно, Visual Studio хранила ссылку на устаревшую версию библиотеки или где-то кэшировала устаревшую версию.

Вот как я выздоровел из этой ситуации:

  1. Щелкните правой кнопкой мыши на панели инструментов WinForms и выберите Reset Toolbox в контекстном меню. (удаляет пользовательские элементы из панели инструментов).
    В моем случае элементы панели инструментов вернулись в состояние по умолчанию; однако стрелка указателя отсутствовала на панели инструментов.
  2. Закрыть Visual Studio.
    В моем случае Visual Studio прервана с исключением из-за нарушения и прервана.
  3. Перезапустите Visual Studio.
    Теперь все идет гладко.
3 голосов
/ 10 февраля 2017

Я столкнулся почти с той же проблемой. Я почесал голову, что является причиной этой ошибки. Я перепроверил, все методы были реализованы.

На Google, я получил эту ссылку среди других. Основываясь на комментарии @Paul McLink, эти два шага решили проблему.

  1. Перезапустите Visual Studio
  2. Очистить, построить (перестроить)

и ошибка исчезла .

Перезапустить плагин VS

Спасибо, Пол:)

Надеюсь, это поможет кому-то, кто сталкивался с этой ошибкой:)

3 голосов
/ 28 октября 2016

В моем случае я ранее ссылался на проект mylib в папке одного из участников за пределами репозитория - назовем это v1.0.

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

Позже я сделал это правильно и использовал его через подмодуль git - давайте назовем это v2.0. Однако один проект consoleApp не был обновлен должным образом. Он все еще ссылался на старый v1.0 проект вне моего git-проекта.

сбивает с толку , хотя *.csproj был явно неправильным и указывал на v1.0, среда IDE Visual Studio показала путь как проект v2.0! F12 для проверки интерфейса и класса также перешел на версию v2.0.

Сборка, помещенная компилятором в папку bin, была v1.0 версией, отсюда и головная боль.

Тот факт, что IDE лгала мне, усложнил понимание ошибки.

Решение : Удалил ссылки на проекты из ConsoleApp и прочитал их.

Общий совет: Перекомпилируйте все сборки с нуля (где это возможно, конечно, нельзя для пакетов nuget) и проверьте отметки даты и времени в папке bin\debug. Любые старые датированные сборки - ваша проблема.

...