Ce qui suit pourrait être des connaissances générales qui me manquaient, mais hein. Il y a quelque temps, nous avions un cas de bogue qui comprenait des propriétés virtuelles. Résumant un peu le contexte, considérez le code suivant et appliquez le point d'arrêt à la zone spécifiée:
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 { } }
}
Dans le Derived
contexte de l' objet, vous pouvez obtenir le même comportement lors de l'ajout en base.Property
tant que montre ou de la saisie base.Property
dans la montre rapide.
Cela m'a pris un peu de temps pour réaliser ce qui se passait. Au final, j'ai été éclairé par la Quickwatch. Lorsque vous accédez à la Quickwatch et explorez l' Derived
objet d (ou à partir du contexte de l'objet this
) et sélectionnez le champ base
, le champ d'édition en haut de la Quickwatch affiche la distribution suivante:
((TestProject1.Base)(d))
Ce qui signifie que si la base est remplacée en tant que telle, l'appel serait
public string BaseProperty { get { return ((TestProject1.Base)(d)).Property; } private set { } }
pour les montres, Quickwatch et les info-bulles de débogage de la souris, et il serait alors logique qu'il s'affiche "AWESOME"
au lieu de "BASE_AWESOME"
considérer le polymorphisme. Je ne sais toujours pas pourquoi cela le transformerait en distribution, une hypothèse est que cela call
pourrait ne pas être disponible dans le contexte de ces modules, et seulementcallvirt
.
Quoi qu'il en soit, cela ne change évidemment rien en termes de fonctionnalités, cela Derived.BaseProperty
reviendra toujours vraiment "BASE_AWESOME"
, et donc ce n'était pas la racine de notre bogue au travail, simplement un composant déroutant. J'ai toutefois trouvé intéressant de voir comment cela pouvait induire les développeurs en erreur qui ne le Base
sauraient pas lors de leurs sessions de débogage, en particulier s'il n'est pas exposé dans votre projet mais plutôt référencé comme une DLL tierce, ce qui fait que les développeurs disent simplement:
"Oi, wait..what? Omg que DLL est comme, .. faisant quelque chose de drôle"