为什么不能在即时窗口中评估lambdas?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么不能在即时窗口中评估lambdas?相关的知识,希望对你有一定的参考价值。

有什么特别的原因吗?它根本不可能或者它还没有实现吗?也许有任何第三方插件允许lambda评估?

更新:

我在codeplex Extended Immediate Window上找到了这个项目。似乎已经放弃了一段时间,但这可以证明一个概念。有没有人知道任何其他即时窗口扩展插件?那些可以在C#中运行/ foreach语句的例子?

答案

微软的JaredPar写了几篇回答你问题的博客文章:part 1part 2。你会在那里找到答案。

另一答案

在编写lambda时,捕获变量的行为会显着改变底层代码的构造(将变量移动到编译器生成的类的字段中,这很容易本身就是链式闭包 - 上下文)。

甚至不考虑这样做的一般复杂性,它将有两个选择:

  • 将所有变量值捕获为常量;可行且非常简单,但很容易意味着在即时窗口中执行的结果与在主体中执行的结果非常不同(非常不合需要)
  • 在运行中重写整个代码(出于上述原因)(猜测,不可能)

鉴于“不受欢迎”和“不可能”之间的选择,我猜他们只是选择不实现本身脆弱且写入非常复杂的功能。

另一答案

好吧,我认为这是因为即时窗口只能评估表达式,或者说它只能进行调用和分配。要评估Lambda表达式,必须为该lambda创建一个闭包,然后执行typchecked然后执行。

我认为它归结为立即窗口只是一个评估者,而不是一个解释器。

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

“立即窗口在设计时用于调试和计算表达式,执行语句,打印变量值等。它允许您在调试期间输入要由开发语言评估或执行的表达式。”

所以实际上,你的问题归结为为什么你不能在即时窗口中定义函数(因为lambdas只是匿名函数),而我认为它的答案根本就不是为此而设计的。

另一答案

如果仍需要使用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'.
The 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

另一答案

我假设,因为它是懒惰的评估,立即窗口不能事先知道捕获的变量(闭包)应该具有哪些值。

以上是关于为什么不能在即时窗口中评估lambdas?的主要内容,如果未能解决你的问题,请参考以下文章

Visual Studio 即时窗口 - 不允许使用 Lambda 表达式 - 是不是有解决方法或替代方法? [关闭]

在 intellij 上调试评估表达式

如何从一组中继容器中组合片段?

使用 savedInstanceState 保存和恢复 Kotlin lambda

如何在 XCode 调试器中评估语句

是否可以缓存在 lambda 表达式中评估的值?