2009-06-04 1 views
222

У меня очень странная ошибка на нашей тестовой машине. Ошибка:TypeLoadException говорит «нет реализации», но он реализован

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

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

+12

Мне нравится, как вы делились своим опытом с сообществом, чтобы помочь всем нам, и даже побудили нас прочитать другие ответы тоже, спасибо. К сожалению, ни один из предложений не помог мне. Хотите знать, что в итоге работает для меня? Перезапуск Visual Studio. Почему я не попробовал это первым? –

+0

Спасибо, Пол, прочитав ваш комментарий, я сначала попробовал это.Работал как шарм :-) –

+0

спасибо Пол, спасите меня несколько часов, постоянно царапая мою голову, как обезьяна ... –

ответ

208

ПРИМЕЧАНИЕ - Если этот ответ вам не поможет, пожалуйста, найдите время, чтобы просмотреть другие ответы, которые люди добавили с тех пор.

Короткий ответ

Это может произойти, если вы добавить метод в интерфейс в одну сборку, а затем к реализующего класса в другую сборку, но восстановить реализующий сборки без ссылки на новую версию сборка интерфейса.

В этом случае DummyItem реализует интерфейс из другой сборки. Недавно был добавлен метод SetShort как для интерфейса, так и для DummyItem, но сборка, содержащая DummyItem, была восстановлена, ссылаясь на предыдущую версию сборки интерфейса. Таким образом, метод SetShort эффективно существует, но без волшебного соуса, связывающего его с эквивалентным методом в интерфейсе.

Длинный ответ

Если вы хотите, чтобы попытаться воспроизвести это, попробуйте следующее:

  1. Создать проект библиотеки классов: InterfaceDef, добавить только один класс, и построить:

    public interface IInterface 
    { 
        string GetString(string key); 
        //short GetShort(string key); 
    } 
    
  2. Создайте проект библиотеки второго класса: Реализация (с отдельным решением), скопируйте InterfaceDef.dll в pro Каталог ект и добавить ссылку на файл, добавить только один класс, и построить:

    public class ImplementingClass : IInterface 
    { 
        #region IInterface Members 
        public string GetString(string key) 
        { 
         return "hello world"; 
        } 
    
        //public short GetShort(string key) 
        //{ 
        // return 1; 
        //} 
        #endregion 
    } 
    
  3. Создайте третий, консольный проект: ClientCode, скопируйте два DLLs в директории проекта, добавлять ссылки на файлы, и добавьте следующее код в основной метод:

    IInterface test = new ImplementingClass(); 
    string s = test.GetString("dummykey"); 
    Console.WriteLine(s); 
    Console.ReadKey(); 
    
  4. Выполнить код один раз, консоль говорит «привет мир»

  5. Раскомментируйте код в двух DLL проектов и восстановить - копирование двух библиотек DLL обратно в ClientCode Proje ct, перестроить и попробовать снова запустить. TypeLoadException возникает при попытке создать экземпляр класса ImplementingClass.

+1

Возможно, вам придется добавить, что консольное приложение должно быть перестроено с новыми DLL в качестве ссылки. Простое копирование DLL не будет работать, и это может быть связано с несоответствием версии (т. Е. После компиляции исходной DLL версия изменится). Это справедливое понимание? – shahkalpesh

+0

@shahkalpesh хорошая точка - для меня «работает снова» подразумевается F5. Я обновил ответ. Конечно, все это бы не случилось с хорошим инструментом управления исходными кодами, но не начинайте меня с этого вопроса ... – Benjol

+3

Хм, похоже, что сообщение об ошибке Microsoft имеет ошибку в нем - это говорит о том, что метод класс «DummyItem» не имеет реализации, которая явно ложна .... действительно проблема в том, что метод интерфейса не реализован DummyItem. – Qwertie

31

В дополнение к тому, что уже было сказано самим ответчиком, возможно, стоит отметить следующее. Причина этого в том, что класс может иметь метод с той же сигнатурой, что и метод интерфейса, без реализации этого метода.Следующий код показывает, что:

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 
+0

Это разрешило это для меня, с добавленным уровнем обфускации, что отсутствующий метод, объявленный в интерфейсе, реализованном родительским классом, и объявлен снова в подклассе. Удаление дубликата из подкласса заставило ошибку уйти. – ilikeprogramming

1

Я получил это в службе WCF из-за наличие типа x86 сборки выбранного, в результате чего bisn жить под BIN \ x86 вместо корзины. Выбор любого CPU заставил перекомпилированные библиотеки DLL перейти в правильные местоположения (я не буду подробно останавливаться на том, как это произошло в первую очередь).

18

Я получил это, когда у моего приложения не было ссылки на другую сборку, определяющую класс, который используется в методе в сообщении об ошибке. Запуск PEVerify дал более полезную ошибку: «Система не может найти указанный файл».

11

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

  • проект asp.net содержит сборку A и сборку B, B сильно назван

  • Узла использует Активатор .CreateInstance для загрузки сборки C (т.е. не существует никакой ссылки на C, которая построена отдельно)

  • с был построен ссылки на старую версию сборки B, чем в настоящее время присутствует

Надеюсь, что это поможет кому-то - мне потребовались годы, чтобы понять это.

2

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

16

Я наткнулся на то же сообщение, и вот что мы нашли: Мы используем сторонние библиотеки в нашем проекте. После выхода новой версии мы изменили наш проект, чтобы указать на новый набор DLL и скомпилировать его успешно.

Исключение было брошено, когда я пытался установить один из своих сопряженных классов во время выполнения. Мы позаботились о том, чтобы все остальные ссылки были актуальными, но все равно не повезло. Нам понадобилось время, чтобы обнаружить (используя Обозреватель объектов), что возвращаемый тип метода в сообщении об ошибке был совершенно новым типом из новой, несвязанной сборки.

Мы добавили ссылку на сборку, и ошибка исчезла.

  • Сообщение об ошибке было довольно вводящим в заблуждение, но указывалось более или менее в правильном направлении (правый метод, неправильное сообщение).
  • Исключение возникло, хотя мы не использовали данный метод.
  • Это приводит меня к вопросу: если это исключение бросается в любом случае, почему компилятор не подбирает его?
9

У меня тоже была эта ошибка, она была вызвана любым процессором exe, ссылающимся на любые сборки процессора, которые, в свою очередь, ссылались на сборку x86.

Исключение жаловалось на метод класса в MyApp.Implementations (любой процессор), который получил MyApp.Interfaces (любой процессор), но в fuslogvw.exe я нашел скрытую попытку загрузить программу с неправильным форматом 'исключение из MyApp.CommonTypes (x86), которое используется обоими.

4

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

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

Я перекомпилировать проект А, но не Проект B, который позволил проекту B «ввести» старую версию проекта D dll

+14

Да, мне нравится думать, что проблема [Renault] (http://images.google.com/images?q=renault+logo) – Benjol

+0

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

3

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

3

Другое объяснение этого типа проблемы с использованием управляемого 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, который вызывает проблему as stated by Ayende Rahien on the Rhino Mocks mailing list.

+0

У меня была эта ошибка, когда я использовал тип данных 'System :: Byte'. Я изменил подпись, чтобы принять «неподписанный короткий», а небо снова было синим. – Krishter

3

Эта ошибка также может быть вызвана, если сборка загружается с использованием 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; 
} 
+0

какой-либо полный образец исходного кода? – Kiquenet

5

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

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

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

2

Я также столкнулся с этой проблемой во время запуска моих unittests. Приложение работает нормально и без ошибок. Причиной проблемы в моем случае было то, что я отключил здание тестовых проектов. Реконструкция здания моих тестовых проектов решила проблемы.

12

Я получил эту ошибку в следующем сценарии.

  • Оба Сборки А и B ссылки System.Web.Mvc Version 3.0.0.0
  • Ассамблея указываемые Ассамблеи B и имел классы, реализованные интерфейсы из сборочного B с методами, которые вернулись из классов System.Web.Mvc.
  • Сборка A повышен до System.Web.Mvc версии 4.0.0.0
  • Ассамблея C запускали код ниже (FertPin.Classes.Contact содержится в Ассамблеи A):

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

для меня было исправление ссылки System.Web.Mvc в сборке B до 4.0.0.0. Кажется очевидным сейчас!

Благодаря оригинальному плакату!

+0

У меня было что-то похожее, но наоборот с версиями. Один метод, нацеленный на .NET 2, вернул тип из v2 в System.Windows.Forms. Его переопределенная реализация в сборке .NET с 4 объектами вернула тот же тип, но из v4 в System.Windows.Forms. Он скомпилирован отлично, но ReflectionOnlyLoadFrom не понравилось. –

+0

У меня была аналогичная проблема, связанная с загрузкой типов, которые нацеливали .NET2 на контекст ReflectionOnly приложения .NET4. Я работал над проблемой, перенаправляя все запросы на сборку основных сборщиков .NET2 на свои .NET4-копии в событии AppDomain.ReflectionOnlyAssemblyResolve. – Chaquotay

2

Я видел это в Visual Studio Pro 2008, когда два проекта создавали сборки с тем же именем, один из классов lib SDF.dll, и тот, который ссылался на lib с именем сборки sdf.exe. Когда я сменил название ссылочной сборки, исключение исчезло

1

Это просто означает, что проект реализации устарел в моих случаях. DLL, содержащая интерфейс, была перестроена, но DLL реализации была устаревшей.

3

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

Проверено все ссылки, которые ищут старые файлы, в конце концов я обнаружил, что мне нужно сделать некоторые bindRedirects для 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

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

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

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

Вот как я оправился от этой ситуации:

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

Вот моя ошибка.

Добавлен метод extern, но моя паста была неисправна. DllImportAttribute получил положительную оценку.

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

Обеспечение того, чтобы атрибут был фактически включен в исходный исправленный вопрос.

3

Я продолжаю возвращаться к этому ... Многие из ответов здесь дают большую работу, объясняя, в чем проблема, но не как ее исправить.

Решение этого - вручную удалить файлы bin в опубликованных каталогах проектов. Он очистит все ссылки и заставит проект использовать последние библиотеки DLL.

Я не предлагаю использовать функцию публикации инструментов Удалить, потому что это имеет тенденцию отбрасывать IIS.

-1

Другая возможность - это смесь релизов и отладки в зависимостях. Например, Assembly A зависит от сборки B, A был построен в режиме отладки, а копия B в GAC была построена в режиме Release или наоборот.

2

Я получил эту ошибку, потому что у меня был класс в сборке «С», который был на версии 4.5 фреймворка, реализуя интерфейс в сборке «А», который был на версии 4.5.1 структуры и служил в качестве базовый класс к сборке «B», который также был включен в версию 4.5.1. При попытке загрузить сборку «B» система исключила исключение. Кроме того, я установил некоторые пакеты nuget, нацеленные на .net 4.5.1 для всех трех сборок. По какой-то причине, несмотря на то, что ссылки на nuget не показывались в сборке «B», он успешно строился.

Оказалось, что настоящая проблема заключалась в том, что сборки ссылались на разные версии пакета nuget, которые содержали интерфейс, а подпись интерфейса была изменена между версиями.

0

Для решения этой проблемы для меня было Clean и RebuildSolution.

5

У меня есть еще одно эзотерическое решение для этого сообщения об ошибке. Я обновил целевую инфраструктуру с .Net 4.0 до 4.6, и мой проект модульного тестирования дал мне ошибку «Ошибка System.TypeLoadException ... не имеет реализации» при попытке создания. Он также дал второе сообщение об ошибке о том же якобы не реализованном методе, в котором говорилось, что задача «BuildShadowTask» неожиданно завершилась ». Ни один из рекомендаций здесь не помог, поэтому я искал «BuildShadowTask» и нашел a post on MSDN, что привело меня к использованию текстового редактора для удаления этих строк из файла csproj проекта тестового проекта.

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

После этого обе ошибки ушли и проект был построен.

+0

Это был ответ для меня. Я столкнулся с этой ошибкой после обновления с .NET 4.5 до 4.6. – twblamer

1

У меня была та же проблема. Я понял, что моя сборка, загружаемая основной программой, имела некоторые ссылки с «Копировать локальную» в true. Эти локальные копии ссылок искали другие ссылки в той же папке, которых не было, потому что для «Копировать локальную» других ссылок было установлено значение false. После удаления «случайно» скопированных ссылок ошибка исчезла, потому что основная программа была настроена на поиск правильных мест ссылок.По-видимому, локальные копии ссылок привили последовательность вызовов, потому что эти локальные копии использовались вместо исходных, присутствующих в основной программе.

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

3

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

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

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

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

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

Тот факт, что IDE лгал мне, затруднял реализацию ошибки.

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

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

0

В моем случае я пытался использовать TypeBuilder для создания типа. TypeBuilder.CreateType бросил это исключение. В итоге я понял, что мне нужно добавить MethodAttributes.Virtual к атрибутам при вызове TypeBuilder.DefineMethod для метода, который помогает реализовать интерфейс. Это связано с тем, что без этого флага метод не реализует интерфейс, а скорее новый метод с той же сигнатурой (даже без указания MethodAttributes.NewSlot).

1

В качестве дополнения: это также может произойти, если вы обновите пакет nuget, который использовался для создания сборки подделок. Скажем, вы устанавливаете V1.0 пакета nuget и создаете сборку подделок «fakeLibrary.1.0.0.0.Fakes». Затем вы обновляете самую новую версию пакета nuget, скажем, v1.1, которая добавила новый метод в интерфейс. Библиотека Fakes все еще ищет v1.0 библиотеки. Просто удалите поддельную сборку и регенерируйте ее. Если это будет проблемой, возможно, это исправит.

1

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

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

  1. Restart Visual Studio
  2. Clean, Build (Rebuild)

и ошибка пошла.

Restart VS Plugin

Благодаря Paul :)

Надеется, что это помогает кто-то наткнулось на этой ошибку :)

3

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

Выполняя операцию разрешения Autofac, среда выполнения не смогла загрузить одну из сборок. Сообщение об ошибке жаловалось, что Method 'MyMethod' in type 'MyType' from assembly 'ImplementationAssembly' does not have an implementation. Симптомы возникли при работе на виртуальной машине Windows Server 2012 R2, но не произошли на виртуальных машинах Windows 10 или Windows Server 2016.

ImplementationAssembly ссылка System.Collections.Immutable 1.1.37, и содержит реализации интерфейса IMyInterface<T1,T2>, который был определен в отдельном DefinitionAssembly. DefinitionAssembly ссылка System.Collections.Immutable 1.1.36.

Методы от IMyInterface<T1,T2>, которые были «не реализованы», имели параметры типа IImmutableDictionary<TKey, TRow>, который определен в System.Collections.Immutable.

Реальная копия System.Collections.Immutable, найденная в каталоге программ, была версией 1.1.37. На моей Windows Server 2012 R2 VM, GAC содержала копию System.Collections.Immutable 1.1.36. В Windows 10 и Windows Server 2016 GAC содержал копию System.Collections.Immutable 1.1.37. Ошибка загрузки произошла только тогда, когда GAC содержал более старую версию DLL.

Таким образом, основной причиной сбоя сборочной нагрузки является несоответствие ссылок на System.Collections.Immutable. Определение интерфейса и реализация имели идентичные сигнатуры методов, но на самом деле зависели от разных версий System.Collections.Immutable, а это означало, что среда выполнения не учитывала класс реализации в соответствии с определением интерфейса.

Добавления следующего связывающей переадресации файл приложение конфигурация исправил проблему:

<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> 
1

Я получил эту ошибку после недавнего обновления окна. У меня был класс сервисов, наследуемый от интерфейса. Интерфейс содержит подпись, которая вернула ValueTuple, довольно новую функцию на C#.

Все, что я могу догадаться, это то, что обновление Windows установило новый, но даже явно ссылалось на него, обновляя переадресацию связывания и т. Д. Конечный результат заключался в том, что только изменение сигнатуры метода было чем-то «стандартным». ты мог бы сказать.

Смежные вопросы