简体   繁体   中英

Why is it not possible to evaluate lambdas in the immediate window?

Is there any particular reason? Is it not possible at all or is it just not implemented yet? Maybe there are any third-party addins that allow lambda evaluations?

UPDATE:

I've found this project on codeplex Extended Immediate Window . Seems that it has been abandoned for some time, but this can be a proof of a concept. Does anybody know any other immediate window extension addins? The ones that can run for/foreach statements in C# for instance?

JaredPar of Microsoft wrote a couple of blog posts answering your question: part 1 and part 2 . You'll find the answers there.

When writing a lambda, the act of capturing variables significantly alters the construction of the underlying code (moving variables into fields of compiler-generated classes, that could very easily themselves be chained closure-contexts).

Not even considering the general complexity of doing this, it would then have two choices:

  • capture all the variable values as constants; feasible and pretty simple, but could easily mean that the result of executing in the immediate window is very different to the result of executing in the main body (very undesirable)
  • rewrite the entire code (for the reasons outlined above) on the fly (at a guess, impossible)

Given a choice between "undesirable" and "impossible", I guess they simply chose not to implement a feature that would be inherently brittle, and very complex to write.

Well, I think it's because the immediate window can only evaluate expressions, or rather it can only do invocations and assignments. To evaluate a Lambda expression a closure would have to be created for that lambda, typchecked and then executed.

I think it comes down to that the Immediate window is just an evaluator and not an interpreter.

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

"The Immediate window is used at design time to debug and evaluate expressions, execute statements, print variable values, and so forth. It allows you to enter expressions to be evaluated or executed by the development language during debugging."

So in effect, your question boils down to why you can't define functions in the immediate window (since lambdas are just annonymous functions), and the answer I think is that it simply wasn't designed for that.

If you still need to use Visual Studio 2013, you can actually write a loop, or lambda expression in the immediate window using also the package manager console window. In my case, I added a list at the top of the function:

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

Where my GetAll() function is:

    private DbSet<T> _dbSet;

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

        return list;
    }

Here I kept getting the following error, so I wanted to print out all the items in the various repositories:

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}

Then, I find out how many records are in the department repository by executing this in the immediate window:

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

Which returned 243.

So, if you execute the following in the package manager console, it prints out all the items:

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

The author for the idea can be found here: http://ogresoft.blogspot.ca/2013/06/how-to-write-loop-or-lambda-expression.html

我假设,因为它是惰性求值,所以直接窗口无法事先知道捕获的变量(闭包)应该具有哪些值。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM