ต่อไปนี้อาจเป็นความรู้ทั่วไปที่ฉันเพิ่งขาดไป แต่เอ๊ะ ก่อนหน้านี้เรามีกรณีข้อบกพร่องซึ่งรวมถึงคุณสมบัติเสมือนจริง การทำให้บริบทเป็นบิตพิจารณารหัสต่อไปนี้และใช้เบรกพอยต์กับพื้นที่ที่ระบุ:
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 { } }
}
ในขณะที่อยู่ใน Derived
บริบทวัตถุคุณสามารถรับพฤติกรรมแบบเดียวกันเมื่อเพิ่มbase.Property
เป็นนาฬิกาหรือพิมพ์base.Property
ลงใน Quickwatch
เอาฉันสักครู่เพื่อรับรู้ว่าเกิดอะไรขึ้น ในที่สุดฉันก็รู้แจ้งโดย Quickwatch เมื่อเข้าไปใน Quickwatch และสำรวจDerived
วัตถุ d (หรือจากบริบทของวัตถุthis
) และเลือกฟิลด์base
แก้ไขที่อยู่ด้านบนของ Quickwatch จะแสดงการส่งต่อไปนี้:
((TestProject1.Base)(d))
ซึ่งหมายความว่าหากฐานถูกแทนที่เช่นการโทรจะเป็น
public string BaseProperty { get { return ((TestProject1.Base)(d)).Property; } private set { } }
สำหรับนาฬิกา Quickwatch และเคล็ดลับการเลื่อนเมาส์เพื่อแก้ไขข้อบกพร่องและจากนั้นจะทำให้การแสดงผล"AWESOME"
แทน"BASE_AWESOME"
เมื่อพิจารณาถึงความหลากหลาย ฉันยังไม่แน่ใจว่าทำไมมันจึงเปลี่ยนเป็นนักแสดงสมมติฐานหนึ่งคือcall
อาจไม่สามารถใช้ได้จากบริบทของโมดูลเหล่านั้นและมีเพียงcallvirt
อาจไม่สามารถใช้ได้ตั้งแต่บริบทโมดูลเหล่านั้นและมีเพียง
อย่างไรก็ตามที่เห็นได้ชัดว่าไม่ได้เปลี่ยนแปลงอะไรในแง่ของการทำงานDerived.BaseProperty
จะยังคงกลับมาจริงๆ"BASE_AWESOME"
และดังนั้นนี่ไม่ใช่รากของข้อบกพร่องของเราในที่ทำงานเพียงองค์ประกอบที่สับสน อย่างไรก็ตามฉันพบว่ามันน่าสนใจว่ามันจะสร้างความเข้าใจผิดให้กับผู้พัฒนาได้อย่างไรซึ่งจะไม่ทราบถึงความจริงนั้นในระหว่างช่วงการดีบักของพวกเขาโดยเฉพาะถ้าBase
ไม่เปิดเผยในโครงการของคุณ แต่อ้างว่าเป็น DLL ของบุคคลที่สาม
"โอ้เดี๋ยวก่อนแล้วจะเป็นไงดี DLL มันเป็นแบบนั้น .. กำลังทำอะไรตลก ๆ "