2017-10-16 139 views
0

我想實現自定義Lazy<T>類,只是爲了實現它。有趣的是,當我將函數傳遞給構造函數時,在調試器中,我已經可以看到該對象是在函數內創建的,即使實際調用在Value之內。這是因爲調試器自己評估_func還是我不明白Func<>的工作原理?Visual Studio在調試器中調用函數之前調用函數

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

相關問題