Sau đây có thể là kiến thức chung tôi chỉ đơn giản là thiếu, nhưng eh. Thời gian trước, chúng tôi đã có một trường hợp lỗi bao gồm các thuộc tính ảo. Tóm tắt bối cảnh một chút, xem xét đoạn mã sau và áp dụng điểm dừng cho khu vực được chỉ định:
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 { } }
}
Khi ở trong Derived
bối cảnh đối tượng, bạn có thể có hành vi tương tự khi thêm base.Property
dưới dạng đồng hồ hoặc nhậpbase.Property
vào quickwatch.
Mất một thời gian để tôi nhận ra những gì đang xảy ra. Cuối cùng, tôi đã được khai sáng bởi Quickwatch. Khi đi vào Quickwatch và khám phá Derived
đối tượng d (hoặc từ bối cảnh của đối tượng this
) và chọn trườngbase
, trường chỉnh sửa trên đầu Quickwatch sẽ hiển thị các biểu tượng sau:
((TestProject1.Base)(d))
Điều đó có nghĩa là nếu cơ sở được thay thế như vậy, cuộc gọi sẽ là
public string BaseProperty { get { return ((TestProject1.Base)(d)).Property; } private set { } }
đối với Đồng hồ, Quickwatch và các công cụ gỡ lỗi trên chuột, và sau đó nó sẽ có ý nghĩa cho nó hiển thị "AWESOME"
thay vì "BASE_AWESOME"
khi xem xét tính đa hình. Tôi vẫn không chắc tại sao nó lại biến nó thành diễn viên, một giả thuyết cho rằngcall
có thể không có sẵn từ bối cảnh của các mô-đun đó, và chỉ callvirt
.
Dù sao đi nữa, điều đó rõ ràng không làm thay đổi bất cứ điều gì về chức năng, Derived.BaseProperty
vẫn sẽ thực sự quay trở lại "BASE_AWESOME"
, và do đó đây không phải là gốc rễ của lỗi tại nơi làm việc, chỉ đơn giản là một thành phần khó hiểu. Tuy nhiên tôi đã thấy thú vị khi nó có thể đánh lừa các nhà phát triển, những người sẽ không biết về thực tế đó trong các phiên gỡ lỗi của họ, đặc biệt nếu Base
không được tiết lộ trong dự án của bạn mà chỉ được gọi là DLL của bên thứ 3, dẫn đến Devs chỉ nói:
"Oi, đợi đã..cái gì vậy? Omg là DLL như thế nào .. làm gì đó buồn cười"