2013-12-18 30 views
1

我遇到了奇怪的行爲,不知道原因。我有兩個項目A和B.引用System.Web程序集和B引用A.我添加使用語句項目B類using A。它工作正常,直到我開始使用linq語句。 我得到的編譯錯誤當項目需要引用其他dll時

The type 'System.Web.UI.Control' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. 

簡單的例子項目。兩個項目父母和孩子。父項目引用System.Web。子項目引用父項目。 父項目包含一類家長:

using System.Web.UI; 

namespace Parent 
{ 
    public static class Parent 
    { 
     public static T DoStuff<T>(this object obj) 
      where T : Control 
     { 
      return null; 
     } 
    } 
} 

兒童項目包含一個子類:

using System.Collections.Generic; 
using System.Linq; 
using Parent; 

namespace Child 
{ 
    public class Child 
    { 
     void Test() 
     { 
      var strings = new List<string>(); 
      var string1 = strings.FirstOrDefault(); 
     } 
    } 
} 

異常被拋出var string1 = strings.First();。我只是在Child項目中添加對System.Web的引用,並且一切正常。但我想明白爲什麼它像這樣工作。 如果我改變父類:

public static class Parent 
{ 
    public static Control DoStuff(this object obj) 
    { 
     return null; 
    } 
} 

而不是使用泛型的我直接使用控制類。它工作正常。 任何想法?

編輯:var string1 = strings.FirstOrDefault();

回答

3

如果你引用一個項目,把它添加到其編譯的.dll文件的引用。 但是,僅僅因爲你引用了一個dll並不會讓你的項目遞歸地引用被引用的dll所引用的所有dll。

比方說,你添加一個引用到B項目到項目A.雖然項目B的參考System.Web它不會自動引用它在項目A. 如果系統將遞歸引用添加一個dll你會最終得到大量你不需要的參考資料。

這就是爲什麼你還是要引用所有必要的組件手動在項目中使用,以便能夠從項目B.

+0

確定使用的一切。但我不明白的是。 1)我不使用DoStuff方法。 2)爲什麼它只在linq語句上失敗(至少如果我不使用它編譯)3)爲什麼它不工作,只有當控制是在泛型的where子句中定義的,並且當Control是方法的參數或返回類型的方法。 – Kazys

+1

我只是在猜測。不過,我認爲這可能是因爲FirstOrDefault()是一種擴展方法。也許當你調用它開始搜索所有加載的程序集中的所有擴展方法。當他遇到靜態類「Parent」(擴展也在靜態類中)時,他開始在類中搜索擴展方法,並遇到System.Web.UI.Controls類,然後他無法解析該類。然而,這只是猜測,因爲我不知道是什麼原因導致該行在運行時拋出異常。 – RononDex

+0

我想強調的是編譯時錯誤而不是運行時 – Kazys

相關問題