2010-06-14 47 views
20

有什麼特別的原因嗎?這是不可能的,還是隻是沒有實現?也許有任何允許lambda評估的第三方插件?爲什麼不能在即時窗口中評估lambda表達式?

UPDATE:

我發現CodePlex上Extended Immediate Window這個項目。似乎已經放棄了一段時間,但這可能是一個概念的證明。有誰知道任何其他即時窗口擴展插件?例如那些可以在C#中運行/ foreach語句的程序?

回答

15

JaredPar微軟寫了幾個博客帖子回答你的問題:part 1part 2。你會在那裏找到答案。

-1

我假設,因爲它是懶惰的評估,即時窗口不能事先知道捕獲的變量(閉包)應該具有的值。

+1

在直接窗口(或監視窗口)中寫入表達式時,停止執行並在某個範圍內調試器,因此它可以訪問該範圍內的變量。爲什麼不能從這裏抽取變量? – Max 2010-06-14 10:30:28

+0

@最大 - 因爲「捕捉」它們的行爲改變了它們的本性;它們不再是變量(本地) - 它們是編譯器生成的類中的字段。 – 2010-06-16 13:58:40

+0

的確,我同意馬克斯(雖然我不明白減號)。無論如何。在ms連接一個,可以讀取一個有趣的對話,以Mads爲特色(https://connect.microsoft.com/VisualStudio/feedback/details/472999/ability-to-evaluate-lambda-expressions-in-immediate-window?wa=wsignin1 .0)。覈實! – 2010-06-16 22:58:05

4

嗯,我想這是因爲立即窗口只能評估表達式,或者說它只能執行調用和分配。要評估Lambda表達式,必須爲該lambda,typchecked然後執行而創建閉包。

我認爲這歸結爲即時窗口只是一個評估者而不是解釋者。

http://msdn.microsoft.com/en-us/library/f177hahy(VS.80).aspx

「立即窗口在設計時用來調試和評估表達式,執行語句,打印變量值,等等。它可以讓你輸入表達式進行評估或開發語言執行在調試過程中「。

所以實際上,你的問題歸結爲爲什麼你不能在直接窗口中定義函數(因爲lambdas只是匿名函數),我認爲答案就是它不是爲此設計的。

+1

其實它是相反的。即時窗口評估表達式,但它以一種更準確地描述爲解釋的方式進行。 – JaredPar 2010-07-22 17:53:14

5

在編寫lambda時,捕獲變量顯着的行爲改變了底層代碼的構造(將變量移動到編譯器生成的類的字段中,它們本身可能很容易被鏈接在關閉上下文中)。

即使不考慮這樣做的一般複雜,就那麼有兩種選擇:

  • 捕獲所有變量值作爲常量;可行並且非常簡單,但是很容易意味着在立即窗口中執行的結果是不同於在主體中執行的結果(非常不希望的)
  • 重寫整個代碼(出於上述原因)上飛(在猜測,是不可能的)

由於「不受歡迎」和「不可能」,我他們根本沒有選擇執行一個功能,將固有的脆性,很之間的選擇複雜的寫作。

+0

Hacky實現:如果檢測到lambda,則以編程方式將其粘貼到執行停止的行上的代碼中,執行該行,刪除lambda,顯示lambda的輸出。我的直覺是將每一行代碼輸入到即時窗口中,以這種方式執行(或者說,在道義上等同於這種方式)。我不覺得你已經解釋了爲什麼會失敗。 – Brian 2010-06-16 13:30:25

+3

@布萊恩 - 你不可能這樣做,繼續執行。一個lambda捕獲*任何變量等等,都會迫使IL非常不同。一個*不*與任何變量交談的lambda可能並不是非常有趣的開始。 – 2010-06-16 13:53:24

1

如果您仍然需要使用Visual Studio 2013,那麼您實際上可以使用包管理器控制檯窗口在即時窗口中編寫一個循環或lambda表達式。

private void RemoveRoleHierarchy() 
    { 
#if DEBUG 
     var departments = _unitOfWork.DepartmentRepository.GetAll().ToList(); 
     var roleHierarchies = _unitOfWork.RoleHierarchyRepository.GetAll().ToList(); 
#endif 

     try 
     { 
      //RoleHierarchy 
      foreach (SchoolBo.RoleHierarchy item in _listSoRoleHierarchy.Where(r => r.BusinessKeyMatched == false)) 
       _unitOfWork.RoleHierarchyRepository.Remove(item.Id); 

      _unitOfWork.Save(); 
     } 
     catch (Exception e) 
     { 
      Debug.WriteLine(e.ToString()); 
      throw; 
     } 
    } 

凡我GETALL()函數是:在我的情況,我在函數的頂部添加列表

private DbSet<T> _dbSet; 

    public virtual IList<T> GetAll() 
    { 
     List<T> list; 
     IQueryable<T> dbQuery = _dbSet; 
     list = dbQuery 
      .ToList<T>(); 

     return list; 
    } 

在這裏,我一直得到下面的錯誤,所以我想打印出各種信息庫中的所有項目:

InnerException {"The DELETE statement conflicted with the REFERENCE constraint \"FK_dbo.Department_dbo.RoleHierarchy_OranizationalRoleId\". The conflict occurred in database \"CC_Portal_SchoolObjectModel\", table \"dbo.Department\", column 'OranizationalRoleId'.\r\nThe statement has been terminated."} System.Exception {System.Data.SqlClient.SqlException} 

於是,我找出多少條記錄在該部門通過資料庫在即時窗口中執行此:

_unitOfWork.DepartmentRepository.GetAll().ToList().Count 

哪些返回243

所以,如果你執行包管理器控制檯下面,它打印出的所有物品:

PM> for($i = 0; $i -lt 243; $i++) { $a = $dte.Debugger.GetExpression("departments[$i].OrgagnizationalRoleId"); Write-Host $a.Value $i } 

筆者的想法可以在這裏找到:http://ogresoft.blogspot.ca/2013/06/how-to-write-loop-or-lambda-expression.html

+0

在Visual Studio 2012中,您**無法在使用軟件包管理器控制檯窗口的即時窗口中使用_lambda表達式_。看看我的評論[這個答案](https://stackoverflow.com/a/33131266/7794769) – stomy 2018-02-20 18:42:43