2017-10-16 18 views
0

사용자 정의 Lazy<T> 클래스를 구현하려는 경우에만 구현하고 싶습니다. 흥미로운 점은 생성자에 함수를 전달할 때 디버거에서 실제 호출이 Value인데도 객체가 함수 내부에서 만들어진 것을 볼 수 있다는 것입니다. 이것은 디버거가 _func을 평가하기 때문입니까 아니면 Func<>이 작동하는지 이해할 수 없습니까? Visual Studio에서 디버거를 호출하기 전에 func를 평가합니다.

class Program 
{ 
    static void Main(string[] args) 
    { 
     var lazyObj = new LazyTest<Entity>(() => new Entity { Foo = 5 }); // Debugger shows that Entity is already created here and Foo = 5. 
     var entity = lazyObj.Value; // Creation of Entity should happen here. 
     Console.WriteLine(entity.Foo); 

     Console.Read(); 
    } 
} 

public class Entity 
{ 
    public int Foo { get; set; } 
} 

public class LazyTest<T> 
{ 
    private T _value; 
    public T Value 
    { 
     get 
     { 
      if (_value == null) 
       _value = _func(); 
      return _value; 
     } 
    } 
    private Func<T> _func { get; set; } 

    public LazyTest(Func<T> func) 
    { 
     _func = func; 
    } 

나는 Lazy<T> 내부적 특성 internal T ValueForDebugDisplay를 사용하는 것을 발견,하지만 내 질문에 대한 답변입니다 있는지 확실 100 % 아니에요.

답변

2

중단 점을 추가하면 디버거가 현재 범위에있는 변수 및 속성 값을 표시합니다.

: 다음이 값은 지역 창에 표시하지 않을이다

1) DebuggerBrowsable은 절대로 당신의 재산에 속성 없습니다 추가 : 그것은 기본적으로 그들을 평가, 당신은 몇 가지 방법으로이 문제를 접근 할 수 [DebuggerBrowsable (DebuggerBrowsableState.Never)]을

2) Visual Studio에서이 동작하지 않도록 설정 -> 옵션 - 도구> 디버깅 -> 일반 -> 및 을 사용하지

이 "특성 평가 ... 사용" 3) Look how Lazy does it. 우리는 속성이 클래스에 추가 참조 :

[DebuggerDisplay("ThreadSafetyMode={Mode}, IsValueCreated={IsValueCreated}, IsValueFaulted={IsValueFaulted}, Value={ValueForDebugDisplay}")] 
public class Lazy<T> 

당신이 언급 한 속성, ValueForDebugDisplay, 여기에 구현됩니다

internal T ValueForDebugDisplay 
{ 
    get 
    { 
     if (!IsValueCreated) 
     { 
      return default(T); 
     } 
     return ((Boxed)m_boxed).m_value; 
    } 
} 

당신이 그것을 보여주는 것, 그것이 값이 아직 생성되지 않고 볼 수 있듯이 Lazy 제네릭 형식의 기본값입니다.

+0

하지만 내 현재 구현은 실제로 개체를 만들지 또는 디버거가이를 표시 할 목적으로 개체를 만드나요? 메모리에 객체가 할당되는 시점은 언제입니까? 'Value' 또는 이후에 전화하기 전에? – FCin

+0

디버거가 그것을 생성하여 로컬 창에 표시합니다. 디버거가 중단 점에 도달했을 때 발생합니다. 위의 문제에 접근하기위한 몇 가지 방법을 추가했습니다. 행운을냅니다. –

+0

사실, 당신 말이 맞습니다. 나는'Console.WriteLine'을 삽입하여 인쇄 될 때를 보았고'Value'를 호출하거나 디버거의'Value'를 보았을 때 인쇄되는 것으로 밝혀졌습니다. – FCin