InvalidCastException приводит объект к своему собственному типу

StackOverflow https://stackoverflow.com/questions/3895163

Вопрос

В настоящее время я полностью сбит с толку возникшей у меня проблемой.Я пишу плагин для другого приложения, которое предоставляет общедоступный .NET API.Я создал класс с именем Room и я использую PropertyGrid, чтобы позволить пользователям видеть и редактировать свойства Room экземпляры.Некоторые свойства ограничены набором стандартных значений.Таким образом, я использую пользовательские TypeDescriptors с GetStandardValues() переопределяет, чтобы в таблице свойств отображался выпадающий список для этих свойств.

Все это работало просто отлично.У меня были выпадающие списки, и я мог редактировать значения без проблем.Тем не менее, теперь по какой-то причине, когда я выбираю Room PropertyGrid отображает свойства с дескрипторами типов в виде черного ящика.

alt text

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

System.InvalidCastException was caught
  Message=Unable to cast object of type 'DVAMC.Room' to type 'DVAMC.Room'.
  Source=DVAMC
  StackTrace:
       at DVAMC.BuildingTypeConverter.GetStandardValuesSupported(ITypeDescriptorContext context) in C:\Documents and Settings\eric.anastas\My Documents\_SVN WC\DVAMC Working\BuildingTypeConverter.cs:line 14
       at System.Windows.Forms.PropertyGridInternal.GridEntry.get_Flags()
       at System.Windows.Forms.PropertyGridInternal.GridEntry.get_NeedsDropDownButton()
       at System.Windows.Forms.PropertyGridInternal.PropertyDescriptorGridEntry.get_NeedsDropDownButton()
       at System.Windows.Forms.PropertyGridInternal.PropertyGridView.SelectRow(Int32 row)
       at System.Windows.Forms.PropertyGridInternal.PropertyGridView.SelectGridEntry(GridEntry gridEntry, Boolean fPageIn)
       at System.Windows.Forms.PropertyGridInternal.PropertyGridView.GridPositionData.Restore(PropertyGridView gridView)
       at System.Windows.Forms.PropertyGridInternal.PropertyGridView.Refresh(Boolean fullRefresh, Int32 rowStart, Int32 rowEnd)
       at System.Windows.Forms.PropertyGridInternal.PropertyGridView.Refresh()
       at System.Windows.Forms.PropertyGrid.Refresh(Boolean clearCached)
       at System.Windows.Forms.PropertyGrid.set_SelectedObjects(Object[] value)
       at System.Windows.Forms.PropertyGrid.set_SelectedObject(Object value)
       at DVAMC.RoomDetailsForm.set_RoomDetailsSelectedRoom(Room value) in C:\Documents and Settings\eric.anastas\My Documents\_SVN WC\DVAMC Working\RoomDetailsForm.cs:line 115
       at DVAMC.RoomDetailsForm.roomListTreeView_SelectionChanged(Object sender, EventArgs e) in C:\Documents and Settings\eric.anastas\My Documents\_SVN WC\DVAMC Working\RoomDetailsForm.cs:line 159
       at BrightIdeasSoftware.ObjectListView.OnSelectionChanged(EventArgs e)
       at BrightIdeasSoftware.ObjectListView.HandleApplicationIdle(Object sender, EventArgs e)
       at System.Windows.Forms.Application.ThreadContext.System.Windows.Forms.UnsafeNativeMethods.IMsoComponent.FDoIdle(Int32 grfidlef)
       at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.RunDialog(Form form)
       at System.Windows.Forms.Form.ShowDialog(IWin32Window owner)
       at System.Windows.Forms.Form.ShowDialog()
       at DVAMC.RoomDetailsCmd.Execute(ExternalCommandData commandData, String& message, ElementSet elements) in C:\Documents and Settings\eric.anastas\My Documents\_SVN WC\DVAMC Working\RoomDetailsCmd.cs:line 44
  InnerException: 

Последний элемент в трассировке стека указывает на мой BuildingTypeConverter.Метод GetStandardValuesSupported(), который показан ниже.

GetStandardValuesSupported(System.ComponentModel.ITypeDescriptorContext context)
{
    Room r = (Room)context.Instance; //this is line 14 referenced by the InvalidCastException's stack trace

    if (r.IsLinked)
    {
        return true;
    }
    else
    {
        return false;
    }
}

Теперь, если я установлю точку останова в строке 14 выше и попытаюсь выполнить отладку, отладчик не прервется в точке останова.Кроме того, если я добавляю произвольный код перед приведением, трассировка стека из InvalidCastException всегда ссылается на первую строку GetStandardValues(), независимо от того, что это такое.Например, я попробовал следующее.

public override bool GetStandardValuesSupported(System.ComponentModel.ITypeDescriptorContext context)
    {
        string s = "hello world";   //FIRST LINE
        int i = 0;


        Room r = (Room)context.Instance; 

        .....

Я все еще получаю то же самое InvalidCastException.Тем не менее, это ссылка на трассировку стека в первой строке выше, где я инициализирую string s.Кроме того, если я попытался установить точку останова в этой первой строке, она также не сработала.

Как я уже говорил до этого был день или около того назад все работало просто отлично.Я даже пытался вернуться к предыдущим версиям в моем репозитории SVN.Я зашел так далеко, что в первой редакции я создал пользовательский класс дескриптора типа, но все еще сталкивался с проблемой с InvalidCastExceptions.У кого-нибудь есть хоть малейшее представление о том, что происходит?

Это было полезно?

Решение

Если трассировка стека всегда показывает одну и ту же строку, даже после того, как вы изменили код, это будет указывать мне, что ProperyGrid не использует ту же версию сборки.Это еще раз подтверждается, когда вы говорите, что поставили точку останова, но точка останова так и не была достигнута.Если вы работаете внутри отладчика для Visual Studio, я предлагаю вам взглянуть на окно вывода (Ctrl + W, O), в котором будут перечислены все сборки (с указанием их пути), которые загружаются при запуске.Я видел путаницу с версиями сборки, особенно когда сборка находится в GAC, где она настаивает на загрузке более старой версии сборки.

Другие советы

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

Самый простой способ проверить это - поместить точку останова в то место, где генерируется исключение.Затем вы можете просмотреть эти два типа в разделе часы или немедленное окно и посмотреть на o1.GetType().Assembly. FullName (и аналогично для другого объекта).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top