Я нашел странное поведение в VS2015 Вот подробности:
У меня есть проект .Net 4.6, ссылающийся на сборку 3.5. Эта сборка определяет в одном из них интерфейсы следующий метод, который я смог проверить с помощью декомпилятора Resharper.
void WriteString([MarshalAs(UnmanagedType.BStr), In] string data, [In] bool flushAndEND = true);
Обратите внимание на последний необязательный аргумент flushAndEND, который имеет значение по умолчанию true. Проблема теперь в том, что когда я использую этот метод в моем проекте, зависание над именем метода показывает обычный VS toolTip, который детализирует подпись метода, за исключением того, что для меня это показывает неправильное значение по умолчанию необязательного аргумента flushAndEND. Вот скриншот
Чтобы все было еще хуже, я заметил, что во время выполнения при вызове метода WriteString только с первым параметром flushAndEND устанавливается значение false, а не его значение по умолчанию, определенное в DLL. Я реферирование. Воздействие этого на наш проект было большим, потому что оно оказало большую особенность нашего приложения бесполезным и заблокировало большую часть наших регрессионных тестов.
Мне удалось преодолеть эту проблему, вынудив значение необязательного аргумента true при вызове метода, но я боюсь, что в проекте есть другие вызовы, которые страдают от одной и той же проблемы. Поэтому мне понадобится лучшее решение для этого или, по крайней мере, понять, в чем причина такого поведения.
Мы только что обновили нашу среду несколько недель назад. До того, как мы использовали VS2013, все работало нормально.
Я знаю подтвержденную .Net 4.6 ошибку, которая заставляет некоторые аргументы передавать неправильные значения, и я могу связать их с моей проблемой здесь, но, как говорится в статье, ошибка возникает только при компиляции для архитектуры x64. Мой проект - это приложение WPF, и мы скомпилируем его как x32.
Почему WriteString вызывается с неправильным аргументом по умолчанию?
Я попытаюсь позже изолировать проблему в небольшом проекте и посмотреть, могу ли я воспроизвести проблему.
EDIT: мне удалось изолировать проблему и найти интересные вещи!
Я создал простое консольное приложение .Net 4.6, добавил ссылку на свою Dll и написал следующий простой код, который состоит из отправки команды на устройство и чтения ответа:
private static void Main(string[] args)
{
//Init managers
ResourceManager ioMgr = new ResourceManagerClass();
FormattedIO488 instrument = new FormattedIO488Class();
//Connect to the USB device
instrument.IO = (IMessage)ioMgr.Open("USB0::0x0957::0x0909::MY46312358::0::INSTR");
string cmd = "*IDN?";
//This is the problematic method from my dll
instrument.WriteString(cmd);
//Read the response
string responseString = instrument.ReadString();
Console.WriteLine(responseString);
Console.ReadKey();
}
Что я сделал дальше, открыт этот проект из VS 2013 и VS 2015. В обеих версиях VS я перестраивал проект и запускал его. Вот результаты:
VS2013: WriteString вызывается с использованием значения CORRECT по умолчанию flushAndEND (которое true означает сброс буфера и завершение команды).
VS2015: WriteString вызывается с использованием значения WRONG по умолчанию flushAndEND, которое дало исключение тайм-аута.
Дальнейшие проверки между двумя версиями Visual Studio показывают, что средство просмотра браузера объектов в VS2013 показывает подпись метода как:
void WriteString(string data, [bool flushAndEND = True])
в то время как браузер объекта в VS2015 показывает подпись метода как:
void WriteString(string data, [bool flushAndEND = False])
Единственное объяснение этого поведения заключается в том, что проблема с компилятором VS2015 не считывает правильные значения по умолчанию из сборки.
