2010-10-05 17 views
0

今天奇特的東西發生了,而在VS 2008調試我將給一小段代碼奇特行爲2008

List<IPageHandler> myPageList = TaskSOM.PageList; 

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

在運行類型轉換失敗,APAGE成爲空的應用程序(即是調試原因)。所以所有使用該可變參數的代碼都失敗了。但在調試期間,myPageList中的第一個元素是一個PageHandler。當我在即時窗口中執行該行時

PageHandler aPage = myPageList[0] as PageHandler; 

aPage變量具有適當的值。但是,如果將調試器移動到該行並執行,我會得到一個空值。由於保密性,我無法分享整個代碼。但是有沒有人在過去的窗口中遇到過這樣的問題。有沒有關於直接窗口如何工作的任何材料。

回答

1

這將是代碼的一個很好的例子,你想用運營商。很明顯,你無法承受劇組失敗,或者你會包含一個空測試,並在劇組失敗時做了一些有意義的事情。

使用真正的演員。爲什麼投失敗,你會得到一個異常信息,讓您更好的暗示:

PageHandler aPage = (PageHandler)myPageList[0]; 

例外的是你的朋友,不要回避他們。大膽猜測:當您在線程中使用COM對象並且COM服務器不支持封送處理時,可能會發生這種情況。如果是這種情況,那麼異常消息會告訴你。

+0

感謝您的快速回復。我發現了這個問題。我將添加另一篇文章,以提供完整的細節。 – ferosekhanj 2010-10-06 11:22:47

+0

我已經給出了這個問題的答案。但是我仍然不明白相同類型的演員如何在即時窗口中工作。 – ferosekhanj 2010-10-06 12:42:13

+0

如果您編寫一個特殊的裝配轉儲工具,Assembly.LoadFile()應該僅用於*。使用LoadFrom()。 – 2010-10-06 12:48:27

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,所以應用程序的一部分從[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(); 
      } 
     } 
}