2008年のVSの即時窓の独特の動作
-
27-09-2019 - |
質問
今日、2008年のvsでデバッグ中に特異なことが起こりました。小さなコードスニペットに渡します
List<IPageHandler> myPageList = TaskSOM.PageList;
if( myPageList != null && myPageList.Count > 0 )
{
PageHandler aPage = myPageList[0] as PageHandler;
...; // Some more code below
}
アプリケーションを実行している間、タイプキャストは失敗し、Apageはnullになりました(それがデバッグの理由でした)。そのため、そのvaiableを使用していたすべてのコードは失敗しました。しかし、デバッグ中、MyPagelistの最初の要素はPageHandlerの証書でした。すぐにウィンドウで行を実行するとき
PageHandler aPage = myPageList[0] as PageHandler;
APAGE変数には適切な値があります。しかし、デバッガーをそのラインに移動して実行すると、ヌルが表示されます。機密性があるため、コード全体を共有できませんでした。しかし、過去に誰もがすぐに窓にそのような問題に直面したことがありますか。即時のウィンドウの仕組みに関する資料はありますか。
解決
これはあなたがいるコードの非常に良い例です しないでください 使用したい なので オペレーター。明らかに、キャストを失敗させる余裕がないか、ヌルテストを含めて、キャストが失敗した場合に意味のあることをしました。
本物のキャストを使用してください。キャストが失敗した理由をはるかに良いヒントを与える有益な例外が得られます。
PageHandler aPage = (PageHandler)myPageList[0];
例外はあなたの友人です、それらを避けないでください。ワイルド推測をする:これは、スレッドでcomオブジェクトを使用し、comサーバーがマーシャリングをサポートしていない場合に発生する可能性があります。もしそうなら、例外メッセージはあなたにそれを伝えます。
他のヒント
ここに完全な詳細があります。例外はでした
[A]SimpleClassLib.PageHandler cannot be cast to [B]SimpleClassLib.PageHandler. Type A originates from 'SimpleClassLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' in the context 'LoadNeither' at location 'D:...\bin\SimpleClassLib.dll'. Type B originates from 'SimpleClassLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' in the context 'Default' at location 'D:...\bin\Debug\SimpleClassLib.dll'
開発者は、[a] d: bin simpleclasslib.dllをアプリケーション構成ファイルのいずれかで言及し、[b] d: bin debug simpleclasslib.dllで実際のアプリを構築しました。アプリケーションは[A]からPageHandlerインスタンスを作成し、リストに記入し、他の部分は[B]からPageHandlerにキャストを入力しようとしていました。
次の例では、このエラーを簡単にトリガーします。これが誰かを助けることを願っています。これはシンプルなクラスライブラリです。これをDLLとして構築します。
// SimpleClassLib.dll
namespace SimpleClassLib
{
public class Foo
{
string Prop1 { get { return "I am Foo!!"; } }
}
}
以下はコンソールアプリです。アプリは、vs 2008からの通常の参照のようなsimpleclasslibにリンクします。また、別のパスからインスタンスをロードします。
// Separate console application App.exe
// Progoram.cs
using SimpleClassLib;
namespace App
{
class Program
{
List<object> myFooList;
Program()
{
myFooList = new List<object>();
Assembly a = Assembly.LoadFile(@"<differentpath>\SimpleClassLib.dll");
Type aFooType = a.GetType("SimpleClassLib.Foo");
ConstructorInfo aConstructor = aFooType.GetConstructor(new Type[] { });
myFooList.Add(aConstructor.Invoke(new object[]{}));
myFooList.Add(aConstructor.Invoke(new object[] { }));
myFooList.Add(aConstructor.Invoke(new object[] { }));
}
void DumpPeculiar()
{
for (int i = 0; i < myFooList.Count; i++)
{
// If one inspects the list in debugger will see a list of
// Foo but this Foo comes from a different load context so the
// following cast will fail. While if one executes the line
// f = myFooList[i] as Foo
// it will succeed
Foo f = myFooList[i] as Foo;
Foo f1 = (Foo)myFooList[i];
}
}
static void Main(string[] args)
{
Program p = new Program();
p.DumpPeculiar();
}
}
}