O seguinte pode ser de conhecimento geral que simplesmente estava faltando, mas eh. Há algum tempo, tivemos um caso de erro que incluía propriedades virtuais. Abstraindo um pouco o contexto, considere o código a seguir e aplique o ponto de interrupção na área especificada:
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 { } }
}
Enquanto estiver no Derived
contexto do objeto, você poderá obter o mesmo comportamento ao adicionar base.Property
como um relógio ou digitar base.Property
no quickwatch.
Levei algum tempo para perceber o que estava acontecendo. No final, fui esclarecido pelo Quickwatch. Ao acessar o Quickwatch e explorar o Derived
objeto d (ou a partir do contexto do objeto this
) e selecionar o campo base
, o campo de edição na parte superior do Quickwatch exibe o seguinte elenco:
((TestProject1.Base)(d))
O que significa que, se a base for substituída como tal, a chamada será
public string BaseProperty { get { return ((TestProject1.Base)(d)).Property; } private set { } }
para o Watches, Quickwatch e as dicas de ferramentas de depuração do mouse, e faria sentido exibir isso em "AWESOME"
vez de "BASE_AWESOME"
considerar o polimorfismo. Ainda não sei por que isso a transformaria em elenco, uma hipótese é que call
talvez não esteja disponível no contexto desses módulos e apenas callvirt
.
De qualquer forma, isso obviamente não altera nada em termos de funcionalidade, Derived.BaseProperty
ainda retornará realmente "BASE_AWESOME"
, e, portanto, essa não foi a raiz do nosso bug no trabalho, apenas um componente confuso. No entanto, achei interessante como isso poderia enganar os desenvolvedores que desconhecem esse fato durante as sessões de depuração, especialmente se Base
não estiverem expostos no seu projeto, mas referenciados como uma DLL de terceiros, resultando em Devs dizendo:
"Oi, espere .. o que? Omg que DLL é como, .. fazendo algo engraçado"