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

时间:2010-06-14 10:12:20

标签: c# visual-studio debugging lambda

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

更新

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

5 个答案:

答案 0 :(得分:15)

微软的

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

答案 1 :(得分:5)

在编写lambda时,捕获变量的行为会改变底层代码的构造(将变量移动到编译器生成的类的字段中,这很可能很容易被链式封闭 - 上下文)

即使考虑到这样做的一般复杂性,它也会有两个选择:

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

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

答案 2 :(得分:4)

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

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

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

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

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

答案 3 :(得分:1)

如果您仍然需要使用Visual Studio 2013,您实际上可以使用包管理器控制台窗口在即时窗口中编写循环或lambda表达式。就我而言,我在函数顶部添加了一个列表:

int h = 0;
for (int i = 0; i < rows; i++)
{
    for (int j = 0; j < columnCounter; j++)
    {
        twoDimArray[i, j] = (int)Char.GetNumericValue(charArray[h]);
        //throw exception if the array contains numbers other than 1 or 0
        if (twoDimArray[i, j] != 1 && twoDimArray[i, j] != 0)
            throw new ArgumentException();
        h++;
    }
    h++;
}

我的GetAll()函数是:

    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;
        }
    }

这里我一直收到以下错误,所以我想打印出各个存储库中的所有项目:

    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}

返回了243。

因此,如果您在包管理器控制台中执行以下操作,它将打印出所有项目:

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

这个想法的作者可以在这里找到:http://ogresoft.blogspot.ca/2013/06/how-to-write-loop-or-lambda-expression.html

答案 4 :(得分:0)

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