"빠른 조사"창에서 디버깅하는 동안 람다 식을 사용할 수없는 이유는 무엇입니까?
UPD : 참조
http://blogs.msdn.com/b/jaredpar/archive/2009/08/26/why-no-linq-in-debugger-windows.aspx
"빠른 조사"창에서 디버깅하는 동안 람다 식을 사용할 수없는 이유는 무엇입니까?
UPD : 참조
http://blogs.msdn.com/b/jaredpar/archive/2009/08/26/why-no-linq-in-debugger-windows.aspx
답변:
아니요, 감시 / 지역 / 직접 창에서 람다 식을 사용할 수 없습니다. Marc가 지적했듯이 이것은 매우 복잡합니다. 그래도 주제에 대해 좀 더 자세히 알아보고 싶었습니다.
대부분의 사람들이 디버거에서 익명 함수를 실행할 때 고려하지 않는 것은 진공 상태에서 발생하지 않는다는 것입니다. 익명 함수를 정의하고 실행하는 바로 그 행위는 코드베이스의 기본 구조를 변경합니다. 일반적으로 특히 즉각적인 창에서 코드를 변경하는 것은 매우 어려운 작업입니다.
다음 코드를 고려하십시오.
void Example() {
var v1 = 42;
var v2 = 56;
Func<int> func1 = () => v1;
System.Diagnostics.Debugger.Break();
var v3 = v1 + v2;
}
이 특정 코드는 v1 값을 캡처하기 위해 단일 클로저를 생성합니다. 익명 함수가 범위 밖에서 선언 된 변수를 사용할 때마다 클로저 캡처가 필요합니다. 모든 의도와 목적을 위해 v1은 더 이상이 기능에 존재하지 않습니다. 마지막 줄은 실제로 다음과 비슷합니다.
var v3 = closure1.v1 + v2;
Example 함수가 디버거에서 실행되면 Break 라인에서 중지됩니다. 이제 사용자가 감시 창에 다음을 입력했다고 상상해보십시오.
(Func<int>)(() => v2);
이를 제대로 실행하기 위해 디버거 (또는 더 적절한 EE)는 변수 v2에 대한 클로저를 생성해야합니다. 이것은 어렵지만 불가능하지는 않습니다.
이것이 EE에게 정말 힘든 일을 만드는 것은 마지막 라인입니다. 이제 그 라인을 어떻게 실행해야합니까? 모든 의도와 목적을 위해 익명 함수는 v2 변수를 삭제하고이를 closure2.v2로 대체했습니다. 따라서 코드의 마지막 줄은 이제 실제로 읽어야합니다.
var v3 = closure1.v1 + closure2.v2;
그러나 실제로 코드에서이 효과를 얻으려면 EE가 실제로 ENC 작업 인 코드의 마지막 줄을 변경해야합니다. 이 특정 예는 가능하지만 시나리오의 좋은 부분은 그렇지 않습니다.
더 나쁜 것은 람다 표현식이 새로운 클로저를 생성하지 않아야한다는 것입니다. 실제로 원래 클로저에 데이터를 추가해야합니다. 이 시점에서 ENC 한계로 곧장 실행됩니다.
내 작은 예는 불행히도 우리가 직면 한 문제의 표면을 긁는 것뿐입니다. 이 주제에 대한 전체 블로그 게시물을 작성하겠다고 계속 말하고 이번 주말에 시간이 있기를 바랍니다.
직접 실행 또는 조사 식 창에서는 람다 식을 사용할 수 없습니다.
그러나 .Where ( "Id = @ 0", 2) 형식을 취하는 System.Linq.Dynamic 식을 사용할 수 있습니다. 표준 Linq에서 사용할 수있는 전체 메서드 범위가없고 전체가 없습니다. 람다 식의 힘이지만 여전히 아무것도없는 것보다 낫습니다!
.Any(string predicate)
, Watch Window 또는 Pin to Source 와 같은 것을 넣을 수 있습니다.Where("Id>2").Any()
. 훌륭합니다!
미래가 왔습니다!
람다 식 디버깅에 대한 지원이 Visual Studio 2015 에 추가되었습니다 ( 작성 당시 미리보기 ).
Expression Evaluator를 다시 작성해야했기 때문에 ASP.NET 원격 디버깅, 직접 실행 창에서 변수 선언, 동적 변수 검사 등 많은 기능이 누락되었습니다. 또한 네이티브 함수를 호출해야하는 람다 식은 현재 지원되지 않습니다.
도움이 될 수 있습니다 : Visual Studio 용 확장 직접 실행 창 (디버깅에서 Linq, Lambda Expr 사용)
최선을 다해, Patrick
람다 식은 디버거의 식 평가 기에서 지원되지 않습니다. 컴파일 타임에식이 아닌 메서드 (또는 식 트리)를 생성하는 데 사용되기 때문에 놀라운 일이 아닙니다 (디스플레이가. 그들을 참조하십시오).
물론 그들은 폐쇄, 또 다른 전체 구조 층을 형성 할 수 있습니다.
Expression
나무를 만들 수 있습니다 -그것은 상황에 따라 다릅니다.
VS 2015에서는 지금 그렇게 할 수 있습니다. 이것은 그들이 추가 한 새로운 기능 중 하나입니다.
Visual Studio 2013을 계속 사용해야하는 경우 패키지 관리자 콘솔 창을 사용하여 직접 실행 창에 루프 또는 람다 식을 실제로 작성할 수 있습니다. 제 경우에는 함수 상단에 목록을 추가했습니다.
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 { "DELETE 문이 REFERENCE 제약 조건 \"FK_dbo.Department_dbo.RoleHierarchy_OranizationalRoleId \ "와 충돌했습니다. 충돌은 데이터베이스 \"CC_Portal_SchoolObjectModel \ ", 테이블 \"dbo.Department \ ", 'OranizationalRoleId'열에서 발생했습니다. \ r \ n 문이 종료되었습니다. "} 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 }
질문에 대답하기 위해 Visual Studio 프로그램 관리자의 공식 설명이 있습니다. 간단히 말해서, VS에서 구현하는 것이 "정말, 정말 어렵습니다". 그러나이 기능은 현재 진행 중입니다 (2014 년 8 월 업데이트 됨).
거기있는 동안 투표를 추가하세요!