Das Folgende könnte allgemeines Wissen sein, das mir einfach fehlte, aber eh. Vor einiger Zeit hatten wir einen Fehlerfall, der virtuelle Eigenschaften enthielt. Wenn Sie den Kontext ein wenig abstrahieren, berücksichtigen Sie den folgenden Code und wenden Sie den Haltepunkt auf den angegebenen Bereich an:
class Program
{
static void Main(string[] args)
{
Derived d = new Derived();
d.Property = "AWESOME";
}
}
class Base
{
string _baseProp;
public virtual string Property
{
get
{
return "BASE_" + _baseProp;
}
set
{
_baseProp = value;
//do work with the base property which might
//not be exposed to derived types
//here
Console.Out.WriteLine("_baseProp is BASE_" + value.ToString());
}
}
}
class Derived : Base
{
string _prop;
public override string Property
{
get { return _prop; }
set
{
_prop = value;
base.Property = value;
} //<- put a breakpoint here then mouse over BaseProperty,
// and then mouse over the base.Property call inside it.
}
public string BaseProperty { get { return base.Property; } private set { } }
}
Im Derived
Objektkontext können Sie dasselbe Verhalten beim Hinzufügen base.Property
als Uhr oder beim Eingeben base.Property
in die Schnelluhr feststellen.
Ich brauchte einige Zeit, um zu erkennen, was los war. Am Ende wurde ich von der Quickwatch erleuchtet. Wenn Sie in die Quickwatch gehen und das Derived
Objekt d (oder aus dem Kontext des Objekts this
) erkunden und das Feld auswählen base
, zeigt das Bearbeitungsfeld oben auf der Quickwatch die folgende Besetzung an:
((TestProject1.Base)(d))
Das heißt, wenn die Basis als solche ersetzt wird, wäre der Anruf
public string BaseProperty { get { return ((TestProject1.Base)(d)).Property; } private set { } }
für die Uhren, Quickwatch und die Debugging-Mouse-Over-Tooltips, und es wäre dann sinnvoll, sie anzuzeigen, "AWESOME"
anstatt den "BASE_AWESOME"
Polymorphismus zu berücksichtigen. Ich bin mir immer noch nicht sicher, warum es sich in eine Besetzung verwandeln würde. Eine Hypothese ist, dass dies call
möglicherweise nicht und nur im Kontext dieser Module verfügbar ist callvirt
.
Wie auch immer, das ändert offensichtlich nichts an der Funktionalität, Derived.BaseProperty
wird immer noch wirklich zurückkehren "BASE_AWESOME"
, und daher war dies nicht die Wurzel unseres Fehlers bei der Arbeit, sondern lediglich eine verwirrende Komponente. Ich fand es jedoch interessant, wie es Entwickler irreführen könnte, die sich dieser Tatsache während ihrer Debug-Sitzungen nicht bewusst wären, insbesondere wenn sie Base
nicht in Ihrem Projekt verfügbar gemacht werden, sondern als DLL eines Drittanbieters bezeichnet werden, was dazu führt, dass Entwickler nur sagen:
"Oi, warte ... was? Omg, wie DLL ist, ... etwas Lustiges zu tun"