开发者

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 I开发者_开发技巧mmediate 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


I assume, that because it is lazy evaluation, the immediate window cannot know beforehand what values, the captured variables (closure), should have.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜