peculiar comportamiento de la ventana inmediata en VS 2008
-
27-09-2019 - |
Pregunta
Hoy ocurrió algo muy especial durante la depuración en VS 2008. Me dará el código pequeño fragmento
List<IPageHandler> myPageList = TaskSOM.PageList;
if( myPageList != null && myPageList.Count > 0 )
{
PageHandler aPage = myPageList[0] as PageHandler;
...; // Some more code below
}
Mientras se ejecuta la aplicación del encasillado falló y apage se convirtió en nulo (que fue la razón para la depuración). Así que todo el código que utilizaba vaiable que fallaron. Sin embargo, durante el primer elemento de depuración en el myPageList era de hecho un PageHandler. Cuando ejecuto la línea en la ventana inmediata ??p>
PageHandler aPage = myPageList[0] as PageHandler;
Variable apage tiene un valor adecuado. Pero si se mueve el depurador a esa línea y ejecutar consigo un nulo. Debido a la confidencialidad no podía compartir el código entero. Pero nadie ha enfrentado a un problema de este tipo con la ventana inmediata en el pasado. ¿Hay alguna importancia relativa respecto de cómo funciona la ventana inmediata.
Solución
Esto sería un muy buen ejemplo de código en el que No desea utilizar el como operador. Es evidente que no puede permitirse el reparto a fallar o se habría incluido una prueba nula e hizo algo significativo si el elenco no.
Usar un reparto real. Usted obtendrá una excepción informativo que le da una mejor idea del porqué el reparto fracasó:
PageHandler aPage = (PageHandler)myPageList[0];
Las excepciones son de su amigo, no evitarlos. Tomar una suposición: esto podría suceder cuando se utiliza un objeto COM en un hilo y el servidor COM no admite el cálculo de referencias. Si ese es el caso, entonces el mensaje de excepción se lo dirá.
Otros consejos
Así que aquí es los detalles completos. La excepción fue
[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'
El desarrollador mencionó [A] D: ... \ bin \ SimpleClassLib.dll en una de expediente de solicitud de configuración y construyó la aplicación real con [B] D: ... \ bin \ Debug \ SimpleClassLib.dll por lo una parte de la aplicación creada ejemplo PageHandler de [a] y se llena la lista y la otra parte estaba tratando de escribir fundido a partir de PageHandler [B].
El siguiente ejemplo desencadenar este error fácilmente. Espero que esto ayude a alguien. Esta es la biblioteca de clases sencilla. Construir esto como un archivo DLL.
// SimpleClassLib.dll
namespace SimpleClassLib
{
public class Foo
{
string Prop1 { get { return "I am Foo!!"; } }
}
}
La siguiente es la aplicación de consola. Los enlaces de aplicaciones a la SimpleClassLib como referencia complemento normal a partir de VS 2008. También se carga una instancia de otro camino.
// 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();
}
}
}