Возможная ошибка компилятора C# 4.0, другие могут проверить?

Так как я не знаю точно, какая часть ее один, который инициировал ошибку, я не совсем уверен, как лучше маркировать ее.

Этим вопросом является побочный продукт, ТАКИМ ОБРАЗОМ, вопрос c# код, кажется, оптимизирован недопустимым способом, таким образом, что объектное значение становится пустым, с которым я попытался помочь Gary вчера вечером. Он был тем, который узнал, что была проблема, я только что уменьшил проблему до более простого проекта и хочу проверку, прежде чем я пойду далее с ним, следовательно этот вопрос сюда.

Я отправлю примечание по Microsoft Connect, если другие могут проверить, что также получают эту проблему, и конечно я надеюсь, что или Jon, Mads или Eric будут смотреть на него также :)

Это включает:

  • 3 проекта, 2 из которых являются библиотеками классов, одна из которых является консольной программой (этот последний не необходим для репродуцирования проблемы, но просто выполняющий это, показывают проблему, тогда как необходимо использовать отражатель и посмотреть на скомпилированный код, если Вы не добавляете его),
  • Неполные ссылки и вывод типа
  • Дженерики

Код доступен здесь: репозиторий кода.

Я отправлю описание ниже того, как сделать проекты, если Вы скорее хотите пачкать руки.

Проблема показывает себя путем создания недопустимого броска в вызове метода, прежде, чем возвратить простой универсальный список, бросая его к чему-то странному прежде, чем возвратить его. Исходный код закончился с броском к булевской переменной, да, булевской переменной. Компилятор добавил бросок от a List к булевской переменной, прежде, чем возвратить результат и сигнатуру метода сказал, что это возвратит a List. Это в свою очередь приводит к нечетным проблемам во времени выполнения, всем от результата вызова метода, который рассматривают "оптимизированным далеко" (исходный вопрос), или катастрофический отказ с также BadImageFormatException или InvalidProgramException или одно из подобных исключений.

Во время моей работы для репродуцирования этого я видел бросок к void[], и текущая версия моего кода теперь бросает к a TypedReference. В одном случае катастрофические отказы Отражателя, таким образом, скорее всего, код был вне надежды в этом случае. Ваш пробег мог бы варьироваться.

Вот то, что сделать для репродуцирования его:

Примечание: Там вероятно, что существует больше минимальных форм, которые воспроизведут проблему, но перемещающий весь код во всего один проект заставил его уйти. Удаление дженериков от классов также заставляет проблему уйти. Код ниже воспроизводит проблему каждый раз для меня, таким образом, я оставляю его, как.

Я приношу извинения за завершенные символы HTML в коде ниже, это - Скидка с цены, сыгравшая шутку на мне, если кто-либо знает, как я могу исправить его, сообщите мне или просто отредактируйте вопрос

  1. Создайте новое решение для Visual Studio 2010 года, содержащее консольное приложение для.NET 4.0
  2. Добавьте два новых проекта, обе библиотеки классов, также.NET 4.0 (я собираюсь предположить, что их называют ClassLibrary1 и ClassLibrary2),
  3. Скорректируйте все проекты использовать полную.NET 4,0 времени выполнения, не только клиентский профиль
  4. Добавьте ссылку в консольном проекте к ClassLibrary2
  5. Добавьте ссылку в ClassLibrary2 к ClassLibrary 1
  6. Удалите два файла Class1.cs, который был добавлен по умолчанию к библиотекам классов
  7. В ClassLibrary1 добавьте ссылку на Систему. Время выполнения. Кэширование
  8. Добавьте новый файл к ClassLibrary1, назовите его DummyCache.cs и вставкой в следующем коде:

    using System;
    using System.Collections.Generic;
    using System.Runtime.Caching;
    
    namespace ClassLibrary1
    {
        public class DummyCache where TModel : new()
        {
            public void TriggerMethod()
            {
            }
            // Try commenting this out, note that it is never called!
            public void TriggerMethod(T value, CacheItemPolicy policy)
            {
            }
            public CacheItemPolicy GetDefaultCacheItemPolicy()
            {
                return null;
            }
            public CacheItemPolicy GetDefaultCacheItemPolicy(IEnumerable dependentKeys, bool createInsertDependency = false)
            {
                return null;
            }
        }
    }
    
  9. Добавьте новый файл к ClassLibrary2, назовите его Dummy.cs и вставкой в следующем коде:

    using System;
    using System.Collections.Generic;
    using ClassLibrary1;
    
    namespace ClassLibrary2
    {
        public class Dummy
        {
            private DummyCache Cache { get; set; }
            public void TryCommentingMeOut()
            {
                Cache.TriggerMethod();
            }
            public List GetDummies()
            {
                var policy = Cache.GetDefaultCacheItemPolicy();
                return new List();
            }
        }
    }
    
  10. Вставка в следующем коде в Program.cs в консольном проекте:

    using System;
    using System.Collections.Generic;
    using ClassLibrary2;
    
    namespace ConsoleApplication23
    {
        class Program
        {
            static void Main(string[] args)
            {
                Dummy dummy = new Dummy();
                // This will crash with InvalidProgramException
                // or BadImageFormatException, or a similar exception
                List dummies = dummy.GetDummies();
            }
        }
    }
    
  11. Сборка, и гарантирует, что нет никаких ошибок компилятора

  12. Теперь попытайтесь запустить программу. Это должно отказать за одним из более ужасных исключений. Я видел и InvalidProgramException и BadImageFormatException, в зависимости от того, что бросок закончил как
  13. Посмотрите на сгенерированный код Макета. GetDummies в Отражателе. Исходный код похож на это:

    public List GetDummies()
    {
        var policy = Cache.GetDefaultCacheItemPolicy();
        return new List();
    }
    

    однако отражатель говорит (для меня, он мог бы отличаться, в котором бросает его, выбрал для Вас, и в одном Отражателе случая, даже разрушенном):

    public List GetDummies()
    {
        List policy = (List)this.Cache.GetDefaultCacheItemPolicy();
        TypedReference CS$1$0000 = (TypedReference) new List();
        return (List) CS$1$0000;
    }
    

Теперь, вот несколько нечетных вещей, вышеупомянутый код катастрофического отказа / недопустимый код в стороне:

  • Library2, который имеет Dummy.GetDummies, выполняет вызов для получения политики кэша по умолчанию в отношении класса от Library1. Это использует вывод типа var policy = ..., и результат CacheItemPolicy объект (пустой указатель в коде, но тип важен).

    Однако ClassLibrary2 не имеет ссылки на Систему. Время выполнения. Кэширование, таким образом, это не должно компилировать.

    И действительно, если Вы комментируете метод в Макете, который называют TryCommentingMeOut, Вы добираетесь:

    Тип 'Система. Время выполнения. Кэширование. CacheItemPolicy' определяется в блоке, на который не ссылаются. Необходимо добавить ссылку на блок 'Система. Время выполнения. Кэширование, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.

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

  • Существует похожий метод в DummyCache, если Вы восстанавливаете метод в Dummy, так, чтобы код снова скомпилировал, и затем прокомментируйте метод в DummyCache это имеет "Попытку, комментируя это" комментарий выше его, Вы получаете ту же ошибку компилятора

10
задан Community 23 May 2017 в 12:13
поделиться

1 ответ

Хорошо, я загрузил ваш код и могу подтвердить проблему, как описано.

Я не проделывал сколько-нибудь обширных работ с этим, но когда я запускаю и отражаю сборку Release, все кажется нормальным (= исключение null ref и чистая разборка).
Рефлектор (6.10.11) вылетал на сборках отладки.

Еще один эксперимент: я подумал об использовании CacheItemPolicies, поэтому я заменил его своим MyCacheItemPolicy (в третьей библиотеке классов), и выскочило такое же исключение BadImageFormat.

В исключении упоминается: {"Неверная двоичная подпись. (Исключение из HRESULT: 0x80131192)"}

2
ответ дан 4 December 2019 в 04:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: