2010-10-05 10 views
0

Aujourd'hui, quelque chose d'étrange est arrivé pendant le débogage dans VS 2008. Je donnerai le petit extrait de codecomportement particulier de la fenêtre immédiate VS 2008

List<IPageHandler> myPageList = TaskSOM.PageList; 

if(myPageList != null && myPageList.Count > 0) 
{ 
    PageHandler aPage = myPageList[0] as PageHandler; 
    ...; // Some more code below 
} 

Pendant l'exécution de l'application transtypage a échoué et APAGE est devenu nul (Ce fut le raison du débogage). Donc tout le code qui utilisait ce vaiable a échoué. Mais lors du débogage, le premier élément de myPageList était en fait un PageHandler. Lorsque j'exécute la ligne dans la fenêtre immédiate

PageHandler aPage = myPageList[0] as PageHandler; 

Une variable de page a une valeur correcte. Mais si déplacer le débogueur à cette ligne et exécuter je reçois une valeur nulle. En raison de la confidentialité, je ne pouvais pas partager tout le code. Mais quelqu'un a-t-il fait face à un tel problème avec la fenêtre immédiate dans le passé. Y a-t-il du matériel concernant le fonctionnement de la fenêtre immédiate?

Répondre

1

Ce serait un très bon exemple de code où vous ne pas veulent utiliser le comme opérateur. Il est clair que vous ne pouvez pas permettre à la distribution d'échouer ou vous auriez inclus un test nul et fait quelque chose de significatif si la distribution a échoué.

Utilisez un réel cast. Vous aurez une exception informative qui vous donne un bien meilleur indice pourquoi le casting a échoué:

PageHandler aPage = (PageHandler)myPageList[0]; 

exceptions sont vos amis, ne pas les éviter. Prenant une conjecture sauvage: cela peut arriver lorsque vous utilisez un objet COM dans un thread et que le serveur COM ne prend pas en charge le marshaling. Si c'est le cas, le message d'exception vous le dira.

+0

Merci pour la réponse rapide. J'ai trouvé le problème. Je vais ajouter un autre message pour donner tous les détails. – ferosekhanj

+0

J'ai donné la réponse à cette question. Mais je ne comprends toujours pas comment le même type de cast fonctionne dans une fenêtre immédiate. – ferosekhanj

+0

Assembly.LoadFile() doit seulement * jamais * être utilisé si vous écrivez un outil de vidage d'assemblage spécial. Utilisez LoadFrom(). –

0

Voici donc tous les détails. L'exception était

[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'

Le promoteur mentionné [A] D: ... \ bin \ SimpleClassLib.dll dans l'un des fichier de configuration d'application et construit l'application réelle avec [B] D: ... \ bin \ Debug \ SimpleClassLib.dll alors une partie de l'application a créé l'instance PageHandler de [A] et a rempli la liste et l'autre partie essayait de taper cast vers PageHandler depuis [B].

L'exemple suivant déclenchera facilement cette erreur. J'espère que cela aide quelqu'un. Ceci est la bibliothèque de classes simple. Construire cela comme un DLL.

// SimpleClassLib.dll  
namespace SimpleClassLib 
    { 
     public class Foo 
     { 
      string Prop1 { get { return "I am Foo!!"; } } 
     } 
    } 

Voici l'application de console. L'application lie à SimpleClassLib comme référence d'ajout normale de VS 2008. Elle charge également une instance d'un autre chemin.

// 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(); 
      } 
     } 
} 
Questions connexes