2010-10-05 4 views
0

Сегодня что-то странное произошло во время отладки в VS 2008. Я дам небольшого фрагмент кодаСвоего поведения немедленного окна в VS 2008

List<IPageHandler> myPageList = TaskSOM.PageList; 

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

Во время работы приложения, к которому не удался, и напечатанный aPage стал нулевым (Это было причина для отладки). Таким образом, весь код, который использовал этот vaiable, не удался. Но во время отладки первый элемент в myPageList был на деле PageHandler. При выполнении строки в непосредственном окне

PageHandler aPage = myPageList[0] as PageHandler; 

переменная aPage имеет правильное значение. Но если переместить отладчик в эту строку и выполнить, я получаю нуль. Из-за конфиденциальности я не мог использовать весь код. Но кто-то сталкивался с такой проблемой с непосредственным окном в прошлом. Есть ли материал относительно того, как работает ближайшее окно.

ответ

1

Это будет очень хороший пример кода, где вы не хотите использовать как оператора. Понятно, что вы не можете допустить, чтобы бросок терпит неудачу, или вы включили бы нулевой тест и сделали бы что-то значимое, если бросок не сработал.

Использование настоящего литья. Вы получите информативный исключение, которое дает вам гораздо лучше намек, почему бросок не удался:

PageHandler aPage = (PageHandler)myPageList[0]; 

Исключением являются вашим другом, не избежать. Принимая дикое предположение: это может произойти, если вы используете COM-объект в потоке, а COM-сервер не поддерживает маршалинг. Если это так, сообщение об исключении скажет вам об этом.

+0

Благодарим за быстрый ответ. Я нашел проблему. Я добавлю еще одну запись, чтобы дать полную информацию. – ferosekhanj

+0

Я дал ответ на этот вопрос. Но все же я не понимаю, как работает тот же тип, что и в ближайшем окне. – ferosekhanj

+0

Assembly.LoadFile() должен использоваться только * когда-либо *, если вы пишете специальный инструмент для сброса сборки. Используйте LoadFrom(). –

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, так что одна часть приложения создала экземпляр PageHandler из [A] и заполнила список, а другая часть пыталась ввести приведение к страницеHandler из [B].

Следующий пример может легко вызвать эту ошибку. Надеюсь, это поможет кому-то. Это простая библиотека классов. Постройте это как 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(); 
      } 
     } 
} 
Смежные вопросы