InvalidCastException独自のタイプにオブジェクトをキャストします
-
29-09-2019 - |
質問
私は現在、私が抱えている問題に完全に困惑しています。パブリック.NET APIを提供する別のアプリケーション用のプラグインを書いています。名前というクラスを作成しました Room
そして、私はユーザーがのプロパティを見て編集できるようにPropertyGridを使用しています Room
インスタンス。いくつかのプロパティは、一連の標準値に制限されています。したがって、私はカスタムTypedescriptorsを使用しています GetStandardValues()
それらのプロパティのドロップダウンを表示するためにプロパティグリッドを取得するためのオーバーライド。
これはすべてうまく機能していました。私はドロップダウンを取得していたので、値を編集することができませんでした。しかし、今では何らかの理由で私が選択したとき Room
PropertyGridには、タイプ記述子がブラックボックスとしてプロパティを表示します。
ボックスをクリックすると、白くなり、点滅するカーソルが表示されますが、何も入力できません。その後、別の部屋を選択すると、次の例外を除いてプログラムがクラッシュします。
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
. 。追加では、この最初の行にブレークポイントを設定しようとした場合、トリガーされませんでした。
私がこの前に言ったように だった 1日前にうまく機能します。 SVNリポジトリの以前の改訂に戻ってみました。私は最初のリビジョンがカスタムタイプの記述子クラスを作成したが、それでも問題に遭遇したので、私は InvalidCastExceptions
. 。何が起こっているのか誰もが考えていますか?
解決
ProperyGridがアセンブリの同じバージョンを実行していないことを私に示すコードを変更した後でも、スタックトレースが常に同じ行を表示する場合。これは、ブレークポイントを置くと言うときにさらに確認されますが、ブレークポイントは決してヒットしません。 Visual Studioのデバッガー内を走っている場合は、出力ウィンドウ(Ctrl+W、O)を見ることをお勧めします。これは、実行中にロードされたすべてのアセンブリ(パスを使用)をリストします。特にアセンブリがGACにあるとき、私はアセンブリ版の混乱を見てきました。そこでは、古いバージョンのアセンブリをロードすることを主張しています。
他のヒント
2つのタイプが実際に異なる可能性があります。たとえば、そのうちの1つが他のタイプよりも別のバージョンのアセンブリからロードされている場合。これがあなたの場合に起こるかどうかはよくわかりませんが、問題になる可能性があります。
これをチェックする最も簡単な方法は、例外がスローされる場所にブレークポイントを配置することです。次に、時計またはすぐにウィンドウの2つのタイプを見て、 o1.GetType().Assembly. FullName
(そして、他のオブジェクトについても同様に)。