今天在VS 2008中进行调试时发生了一些奇怪的事情。我将给出小代码片段
List<IPageHandler> myPageList = TaskSOM.PageList;
if( myPageList != null && myPageList.Count > 0 )
{
PageHandler aPage = myPageList[0] as PageHandler;
...; // Some more code below
}
在运行应用程序时,类型转换失败并且aPage变为null(这是调试的原因)。所以使用该变量的所有代码都失败了。但是在调试期间,myPageList中的第一个元素是一个PageHandler。当我在即时窗口中执行该行
时 PageHandler aPage = myPageList[0] as PageHandler;
aPage变量具有适当的值。但是如果将调试器移动到该行并执行我得到一个null。由于机密性,我无法分享整个代码。但是,过去有任何人都遇到了这个问题。是否存在关于即时窗口如何工作的任何材料。
答案 0 :(得分:1)
这是一个非常好的代码示例,其中不想要将用作运算符。很明显,你无法承受演员阵容的失败,或者如果演员阵容失败,你会包括一个空测试并做一些有意义的事情。
使用真正的演员。您将获得一个信息丰富的异常,为您提供更好的提示,为什么演员会失败:
PageHandler aPage = (PageHandler)myPageList[0];
例外是你的朋友,不要避开它们。猜测一下:当您在线程中使用COM对象并且COM服务器不支持封送时,可能会发生这种情况。如果是这种情况,则异常消息将告诉您。
答案 1 :(得分:0)
所以这是完整的细节。例外是
[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 so应用程序的一部分从[A]创建了PageHandler实例并填充了列表,另一部分试图从[B]中输入强制转换为PageHandler。
以下示例将轻松触发此错误。希望这有助于某人。 这是一个简单的类库。将其构建为dll。
// SimpleClassLib.dll
namespace SimpleClassLib
{
public class Foo
{
string Prop1 { get { return "I am Foo!!"; } }
}
}
以下是控制台应用。该应用程序链接到SimpleClassLib,就像VS 2008中的普通添加引用一样。它还从另一个路径加载一个实例。
// 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();
}
}
}