Berikut ini mungkin pengetahuan umum yang hanya kurang, tapi eh. Beberapa waktu yang lalu, kami memiliki kasus bug yang termasuk properti virtual. Abstraksi konteksnya sedikit, pertimbangkan kode berikut, dan terapkan breakpoint ke area yang ditentukan:
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 { } }
}
Saat berada dalam Derivedkonteks objek, Anda bisa mendapatkan perilaku yang sama saat menambahkan base.Propertysebagai arloji, atau mengetik base.Propertyke arloji cepat.
Butuh waktu untuk menyadari apa yang sedang terjadi. Pada akhirnya saya tercerahkan oleh Quickwatch. Saat membuka Quickwatch dan menjelajahi Derivedobjek d (atau dari konteks objek, this) dan memilih bidang base, bidang edit di atas Quickwatch menampilkan pemeran berikut:
((TestProject1.Base)(d))
Yang berarti bahwa jika pangkalan diganti seperti itu, panggilan akan menjadi
public string BaseProperty { get { return ((TestProject1.Base)(d)).Property; } private set { } }
untuk Arloji, Quickwatch, dan tooltip debug-mouse, dan kemudian masuk akal untuk menampilkannya "AWESOME"daripada "BASE_AWESOME"mempertimbangkan polimorfisme. Saya masih tidak yakin mengapa itu akan mengubahnya menjadi pemain, satu hipotesis adalah bahwa callmungkin tidak tersedia dari konteks modul-modul itu, dan hanya callvirt.
Bagaimanapun, itu jelas tidak mengubah apa pun dalam hal fungsionalitas, Derived.BasePropertymasih akan benar-benar kembali "BASE_AWESOME", dan dengan demikian ini bukan akar bug kami di tempat kerja, hanya komponen yang membingungkan. Namun saya merasa menarik bagaimana itu bisa menyesatkan para pengembang yang tidak menyadari fakta itu selama sesi debug mereka, khususnya jika Basetidak diekspos dalam proyek Anda tetapi lebih dirujuk sebagai DLL pihak ke-3, yang mengakibatkan Devs hanya mengatakan:
"Oi, tunggu..apa? Omg seperti DLL itu, ..melakukan sesuatu yang lucu"