2017-10-16 5 views
0

Ich möchte benutzerdefinierte Lazy<T> Klasse implementieren, nur um es zu implementieren. Interessant ist, dass wenn ich die Funktion an den Konstruktor übergebe, kann ich im Debugger bereits sehen, dass das Objekt innerhalb der Funktion erstellt wurde, obwohl der eigentliche Aufruf innerhalb von Value liegt. Ist das, weil Debugger die _func selbst auswertet oder verstehe ich einfach nicht, wie Func<> funktioniert?Visual Studio wertet func im Debugger aus, bevor es aufgerufen wird

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

Ich fand, dass Lazy<T> intern verwendet Eigenschaft internal T ValueForDebugDisplay, aber ich bin nicht 100% sicher, ob dies eine Antwort auf meine Frage.

Antwort

2

Wenn Sie einen Haltepunkt hinzufügen, zeigt der Debugger Werte von Variablen und Eigenschaften an, die im aktuellen Bereich vorhanden sind. Es ist standardmäßig deren Auswertung, können Sie dieses Verhalten in ein paar Möglichkeiten nähern:

1) Fügen Sie die DebuggerBrowsable Nie, um Ihr Eigentum Attribut, dann ist es Wert nicht in dem Lokalfenster gezeigt werden wird:

[DebuggerBrowsable (DebuggerBrowsableState.Never)]

2) deaktivieren Sie dieses Verhalten in Visual Studio: Extras -> Einstellungen -> Debugging -> Allgemein -> und es deaktivieren "Enable Eigenschaftsbewertung ..."

3) Look how Lazy does it. Wir sehen die Attribute der Klasse hinzugefügt:

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

Die Eigenschaft, die Sie erwähnt, ValueForDebugDisplay wird hier umgesetzt:

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

Wie Sie sehen können, ist es der Wert noch nicht erstellt wird, es zeigt die Standardwert des generischen Lazy-Typs.

+0

Erstellt aber meine aktuelle Implementierung das Objekt oder erstellt der Debugger es, um es anzuzeigen? Wann wird der Speicher für das Objekt zugewiesen? Bevor "Value" oder danach aufgerufen wird? – FCin

+0

Der Debugger erstellt es, um es Ihnen im Fenster Lokal anzuzeigen. Es passiert, wenn der Debugger den Haltepunkt erreicht, habe ich einige Möglichkeiten hinzugefügt, dieses Problem oben zu nähern, viel Glück :) –

+0

Eigentlich haben Sie Recht. Ich habe eine 'Console.WriteLine' eingefügt, um zu sehen, wann sie gedruckt wird und sich herausstellt, dass sie ausgedruckt wird, wenn ich' Value' aufruft oder im Debugger nach 'Value' suche. – FCin

Verwandte Themen