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

  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.

¿Fue útil?

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();
            }
      }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top