Từ ECMA 335 , phần 8.10.4 của phân vùng 1:
CTS cung cấp quyền kiểm soát độc lập đối với cả các tên có thể nhìn thấy từ một loại cơ sở (ẩn) và việc chia sẻ các vị trí bố trí trong lớp dẫn xuất (ghi đè). Ẩn được kiểm soát bằng cách đánh dấu một thành viên trong lớp dẫn xuất là ẩn theo tên hoặc ẩn theo tên và chữ ký. Việc ẩn luôn được thực hiện dựa trên loại thành viên, nghĩa là, tên trường dẫn xuất có thể ẩn tên trường cơ sở, nhưng không ẩn tên phương thức, tên thuộc tính hoặc tên sự kiện. Nếu một thành viên dẫn xuất được đánh dấu là ẩn theo tên, thì các thành viên cùng loại trong lớp cơ sở có cùng tên sẽ không hiển thị trong lớp dẫn xuất; nếu thành viên được đánh dấu là ẩn bằng tên và chữ ký thì chỉ một thành viên cùng loại có tên và kiểu giống hệt nhau (đối với các trường) hoặc chữ ký của phương thức (đối với các phương thức) bị ẩn khỏi lớp dẫn xuất. Việc thực hiện sự phân biệt giữa hai hình thức ẩn này được cung cấp hoàn toàn bởi trình biên dịch ngôn ngữ nguồn và thư viện phản ánh; nó không có tác động trực tiếp đến VES.
(Nó không rõ ràng ngay lập tức từ đó, nhưng hidebysig
có nghĩa là "ẩn bằng tên và chữ ký".)
Cũng trong phần 15.4.2.2 của phân vùng 2:
Hidebysig được cung cấp để sử dụng các công cụ và bị VES bỏ qua. Nó chỉ định rằng phương thức đã khai báo ẩn tất cả các phương thức của các kiểu lớp cơ sở có chữ ký phương thức phù hợp; khi bị bỏ qua, phương thức sẽ ẩn tất cả các phương thức có cùng tên, bất kể chữ ký.
Ví dụ, giả sử bạn có:
public class Base
{
public void Bar()
{
}
}
public class Derived : Base
{
public void Bar(string x)
{
}
}
...
Derived d = new Derived();
d.Bar();
Điều đó hợp lệ, bởi vì Bar(string)
không ẩn Bar()
, vì trình biên dịch C # sử dụng hidebysig
. Nếu nó sử dụng ngữ nghĩa "hide by name", bạn sẽ không thể gọi nó Bar()
trên một tham chiếu kiểu Derived
, mặc dù bạn vẫn có thể truyền nó đến Base và gọi nó theo cách đó.
EDIT: Tôi vừa mới thử điều này bằng cách biên dịch mã ở trên để một DLL, ildasming nó, loại bỏ hidebysig
cho Bar()
và Bar(string)
, ilasming nó một lần nữa, sau đó cố gắng để gọi Bar()
từ mã khác:
Derived d = new Derived();
d.Bar();
Test.cs(6,9): error CS1501: No overload for method 'Bar' takes '0' arguments
Tuy nhiên:
Base d = new Derived();
d.Bar();
(Không có vấn đề biên dịch.)
Shadows
vàOverloads
trong VB.NET.