Từ ECMA 335, phần 8.10.4 của phân vùng 1:
Các CTS cung cấp điều khiển độc lập qua cả những tên tuổi có thể nhìn thấy từ một loại cơ sở (ẩn) và chia sẻ của các khe bố trí trong lớp bắt nguồn (ghi đè). Ẩn là được kiểm soát bằng cách đánh dấu một thành viên trong lớp học có nguồn gốc hoặc ẩn theo tên hoặc ẩn theo tên và chữ ký. Ẩn luôn được thực hiện dựa trên loại của thành viên, có nghĩa là trường bắt nguồn có thể ẩn tên trường cơ sở, nhưng không phải tên phương thức, tên thuộc tính hoặc tên sự kiện. Nếu thành viên có nguồn gốc là được đánh dấu ẩn theo tên, thì thành viên của cùng loại trong lớp cơ sở với cùng tên không hiển thị trong lớp bắt nguồn ; nếu thành viên được đánh dấu ẩn theo tên và chữ ký thì chỉ có thành viên cùng loại với chính xác cùng tên và loại (cho trường) hoặc chữ ký phương thức (cho phương pháp) là bị ẩn khỏi lớp dẫn xuất. Thực hiện phân biệt giữa hai dạng ẩn này là được cung cấp hoàn toàn bằng ngôn ngữ nguồn trình biên dịch và thư viện phản chiếu; nó không có tác động trực tiếp lên bản thân VES .
(Nó không phải ngay lập tức rõ ràng từ đó, nhưng hidebysig
có nghĩa là "ẩn theo tên và chữ ký".)
Cũng trong phần 15.4.2.2 của phân vùng 2:
hidebysig là cung cấp cho việc sử dụng các công cụ và bị VES bỏ qua. Nó chỉ định rằng phương thức được khai báo ẩn tất cả các phương thức của lớp cơ sở các loại có phương thức khớp chữ ký; khi 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ý.
Như một 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();
Đó là hợp lệ, vì Bar(string)
không ẩn Bar()
, bởi vì biên dịch C# sử dụng hidebysig
. Nếu nó sử dụng ngữ nghĩa "ẩn theo tên", bạn sẽ không thể gọi số Bar()
ở tất cả trên tham chiếu loại Derived
, mặc dù bạn vẫn có thể truyền nó đến Base và gọi 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.)
Trong [tóm tắt] (http://stackoverflow.com/a/4760614/256431 "Shadows vs Overloads in VB.NET"), đó là sự khác biệt giữa 'Shadows' và' Overloads' trong VB.NET. –