Результат выражения "is" возвращает false при запуске, но true при проверке
У меня есть следующий код. CustomControlHelper генерирует экземпляр объекта через отражение. На этом этапе мы не знаем, с каким типом объектов мы имеем дело. Мы знаем, что это будет CustomControl
, но мы не знаем, реализует ли он какой-либо конкретный интерфейс или расширяет любые другие классы. Следующий код пытается установить, реализует ли загруженный элемент управления интерфейс IRichAdminCustomControl
.
Object obj = CustomControlHelper.GetControl(cc.Id, cc.ControlClass);
if(obj != null)
{
bool isWhatWeWant = (obj is IRichAdminCustomControl);
return isWhatWeWant;
}
Это все прекрасно, но я заметил, что когда я знаю, что у меня есть объект, реализующий IRichAdminCustomControl
, выражение принимает значение false.
Хорошо, это то, где он становится действительно странным. Если я проверяю код при отладке, выражение оценивается как true, но затем, если я немедленно позволю коду запустить и проверить результат, он оценит значение false (я приложил анимированный gif ниже, чтобы проиллюстрировать).
![enter image description here]()
Кто-нибудь сталкивался с такой странностью, как раньше, и если да, то что на самом деле вызывает это?
Кстати, я считаю, что продукт, который я использую, использует Spring.NET для обеспечения инъекции зависимостей в CustomControlHelper.
Ответы
Ответ 1
Если вы используете Visual Studio 2010 SP1, я наткнулся на эту ошибку:
Неверное представление значений переменных при отладке кода x64
Обходной путь на этой странице, опубликованный Microsoft:
Вы можете либо скомпилировать все проекты на x86, либо создать промежуточное инициализированное объявление переменной, чтобы отладчик сообщал правильное значение проверяемой переменной.
Попробуйте это как обходной путь:
bool isWhatWeWant = true;
isWhatWeWant &= (obj is IRichAdminCustomControl);
bool finalValue = isWhatWeWant; // this line should fix isWhatWeWant too in the debugger
return finalValue;
EDIT: похоже, VS2012 также сталкивается с аналогичными проблемами в определенных условиях.
Ответ 2
Это случилось со мной однажды, и хотя я никогда не приходил к выводу о том, почему это происходит, я считал файлы PDB, которые были загружены с помощью отладочных символов, которые не синхронизированы. Итак, "очистив" решение, а затем перестроив решение, эта странная проблема исчезла.
Ответ 3
Приходят на ум две возможности. Во-первых, ваше имя интерфейса достаточно общее, что оно уже может быть в пространстве имен. Попробуйте полностью определить интерфейс в предложении is. Вторая возможность заключается в том, что вы можете запускать код как часть конструктора или вызываться косвенно конструктором. Любое отражение, подобное материалу, должно быть выполнено после того, как мы уверены, что приложение полностью загружено.
Ответ 4
Итак, я нашел ответ. Это было потому, что у меня было две копии DLL в разных местах. У меня была одна копия в ящике моего внутреннего приложения и одна в общем внешнем каталоге, которая динамически загружается с помощью бэкэнд-приложения.
Я должен объяснить; это приложение состоит из двух приложений, работающих в тандеме, приложения frontend и бэкэнд-приложения. Обычно вы помещаете "Пользовательские элементы управления" в свое приложение frontend. Затем эти элементы управления копируются при запуске приложения во внешний каталог, доступный для бэкэнд-приложения.
В этом случае у меня была логика в моей библиотеке пользовательского контроля, к которой нужно было обращаться в бэкэнд-приложении, поэтому мне пришлось сделать ссылку на нее..., которая закончилась тем, что бэкэнд-приложение имеет две ссылки на одно и то же класс. D'о! И КУРС, который будет работать, когда вы отлаживаете.
Решение заключалось в том, чтобы разделить мою дополнительную логику на свой собственный проект и указать THAT в бэкэнд-приложении.
Я не собираюсь "принимать" свой собственный ответ, потому что, хотя он решил мою конкретную проблему, решение немного TOO, специфичное для приложений, с которыми я работаю, и вряд ли помогло бы кому-либо еще.