Câu trả lời:
Từ docs.microsoft.com :
Loại hoặc thành viên có thể được truy cập bởi bất kỳ mã nào khác trong cùng một hội đồng hoặc một hội đồng khác tham chiếu nó.
Loại hoặc thành viên chỉ có thể được truy cập bằng mã trong cùng một lớp hoặc cấu trúc.
Loại hoặc thành viên chỉ có thể được truy cập bằng mã trong cùng một lớp hoặc cấu trúc, hoặc trong một lớp dẫn xuất.
private protected
(được thêm vào C # 7.2)Loại hoặc thành viên chỉ có thể được truy cập bằng mã trong cùng một lớp hoặc cấu trúc, hoặc trong một lớp dẫn xuất từ cùng một hội đồng, nhưng không phải từ một hội đồng khác.
Loại hoặc thành viên có thể được truy cập bởi bất kỳ mã nào trong cùng một hội đồng, nhưng không phải từ một hội đồng khác.
Loại hoặc thành viên có thể được truy cập bởi bất kỳ mã nào trong cùng một cụm hoặc bởi bất kỳ lớp dẫn xuất nào trong một cụm khác.
Khi không có công cụ sửa đổi truy cập nào được đặt, công cụ sửa đổi truy cập mặc định sẽ được sử dụng. Vì vậy, luôn có một số hình thức sửa đổi truy cập ngay cả khi nó không được đặt.
static
bổ nghĩaCông cụ sửa đổi tĩnh trên một lớp có nghĩa là lớp không thể được khởi tạo và tất cả các thành viên của nó là tĩnh. Một thành viên tĩnh có một phiên bản bất kể có bao nhiêu phiên bản loại kèm theo của nó được tạo.
Một lớp tĩnh về cơ bản giống như một lớp không tĩnh, nhưng có một điểm khác biệt: một lớp tĩnh không thể được khởi tạo bên ngoài. Nói cách khác, bạn không thể sử dụng từ khóa mới để tạo một biến của loại lớp. Vì không có biến đối tượng, bạn truy cập các thành viên của lớp tĩnh bằng cách sử dụng tên lớp.
Tuy nhiên, có một thứ như là một hàm tạo tĩnh . Bất kỳ lớp nào cũng có thể có một trong số này, bao gồm các lớp tĩnh. Chúng không thể được gọi trực tiếp & không thể có các tham số (ngoài bất kỳ tham số loại nào trên chính lớp đó). Một constructor tĩnh được gọi tự động để khởi tạo lớp trước khi phiên bản đầu tiên được tạo hoặc bất kỳ thành viên tĩnh nào được tham chiếu. Trông như thế này:
static class Foo()
{
static Foo()
{
Bar = "fubar";
}
public static string Bar { get; set; }
}
Các lớp tĩnh thường được sử dụng làm dịch vụ, bạn có thể sử dụng chúng như vậy:
MyStaticClass.ServiceMethod(...);
Tổng quan về đồ họa (tóm tắt ngắn gọn)
Vì các lớp tĩnh được niêm phong, chúng không thể được kế thừa (ngoại trừ từ Object), vì vậy từ khóa được bảo vệ là không hợp lệ trên các lớp tĩnh.
Đối với các mặc định nếu bạn không đặt công cụ sửa đổi truy cập ở phía trước, xem tại đây:
Khả năng hiển thị mặc định cho các lớp và thành viên C # (trường, phương thức, v.v.)?
Không lồng nhau
enum public
non-nested classes / structs internal
interfaces internal
delegates in namespace internal
class/struct member(s) private
delegates nested in class/struct private
Lồng nhau:
nested enum public
nested interface public
nested class private
nested struct private
Ngoài ra, có từ khóa kín, làm cho một lớp không kế thừa.
Ngoài ra, trong VB.NET, các từ khóa đôi khi khác nhau, vì vậy đây là một cheat-sheet:
Công khai - Nếu bạn có thể thấy lớp, thì bạn có thể thấy phương thức
Riêng tư - Nếu bạn là một phần của lớp, thì bạn có thể xem phương thức, nếu không thì không.
Được bảo vệ - Giống như Riêng tư, cộng với tất cả con cháu cũng có thể thấy phương thức.
Tĩnh (lớp) - Ghi nhớ sự phân biệt giữa "Lớp" và "Đối tượng"? Quên tất cả đi. Chúng giống nhau với "tĩnh" ... lớp là trường hợp một và duy nhất của chính nó.
Tĩnh (phương thức) - Bất cứ khi nào bạn sử dụng phương thức này, nó sẽ có một khung tham chiếu độc lập với thể hiện thực của lớp mà nó là một phần của.
Đăng lại các sơ đồ tuyệt vời từ câu trả lời này .
Dưới đây là tất cả các sửa đổi truy cập trong sơ đồ Venn, từ hạn chế hơn đến lăng nhăng hơn:
private
:
private protected
: - được thêm vào C # 7.2
internal
:
protected
:
protected internal
:
public
:
using System;
namespace ClassLibrary1
{
public class SameAssemblyBaseClass
{
public string publicVariable = "public";
protected string protectedVariable = "protected";
protected internal string protected_InternalVariable = "protected internal";
internal string internalVariable = "internal";
private string privateVariable = "private";
public void test()
{
// OK
Console.WriteLine(privateVariable);
// OK
Console.WriteLine(publicVariable);
// OK
Console.WriteLine(protectedVariable);
// OK
Console.WriteLine(internalVariable);
// OK
Console.WriteLine(protected_InternalVariable);
}
}
public class SameAssemblyDerivedClass : SameAssemblyBaseClass
{
public void test()
{
SameAssemblyDerivedClass p = new SameAssemblyDerivedClass();
// NOT OK
// Console.WriteLine(privateVariable);
// OK
Console.WriteLine(p.publicVariable);
// OK
Console.WriteLine(p.protectedVariable);
// OK
Console.WriteLine(p.internalVariable);
// OK
Console.WriteLine(p.protected_InternalVariable);
}
}
public class SameAssemblyDifferentClass
{
public SameAssemblyDifferentClass()
{
SameAssemblyBaseClass p = new SameAssemblyBaseClass();
// OK
Console.WriteLine(p.publicVariable);
// OK
Console.WriteLine(p.internalVariable);
// NOT OK
// Console.WriteLine(privateVariable);
// Error : 'ClassLibrary1.SameAssemblyBaseClass.protectedVariable' is inaccessible due to its protection level
//Console.WriteLine(p.protectedVariable);
// OK
Console.WriteLine(p.protected_InternalVariable);
}
}
}
using System;
using ClassLibrary1;
namespace ConsoleApplication4
{
class DifferentAssemblyClass
{
public DifferentAssemblyClass()
{
SameAssemblyBaseClass p = new SameAssemblyBaseClass();
// NOT OK
// Console.WriteLine(p.privateVariable);
// NOT OK
// Console.WriteLine(p.internalVariable);
// OK
Console.WriteLine(p.publicVariable);
// Error : 'ClassLibrary1.SameAssemblyBaseClass.protectedVariable' is inaccessible due to its protection level
// Console.WriteLine(p.protectedVariable);
// Error : 'ClassLibrary1.SameAssemblyBaseClass.protected_InternalVariable' is inaccessible due to its protection level
// Console.WriteLine(p.protected_InternalVariable);
}
}
class DifferentAssemblyDerivedClass : SameAssemblyBaseClass
{
static void Main(string[] args)
{
DifferentAssemblyDerivedClass p = new DifferentAssemblyDerivedClass();
// NOT OK
// Console.WriteLine(p.privateVariable);
// NOT OK
//Console.WriteLine(p.internalVariable);
// OK
Console.WriteLine(p.publicVariable);
// OK
Console.WriteLine(p.protectedVariable);
// OK
Console.WriteLine(p.protected_InternalVariable);
SameAssemblyDerivedClass dd = new SameAssemblyDerivedClass();
dd.test();
}
}
}
Private Protected
, nó sẽ là: cùng một lớp = Yes
, cùng một tổ hợp, lớp dẫn xuất = Yes
, cùng một tổ hợp, bất kỳ lớp nào = NO
, lắp ráp khác nhau, lớp dẫn xuất = NO
, lắp ráp khác nhau, bất kỳ lớp nào = NO
. Một đề xuất bổ sung cũng sẽ không được chuyển đổi thứ tự từ protected internal
, vì điều này phá vỡ pneumonic từ câu trả lời của @ user1810087
Một cách tiếp cận trực quan khác của công cụ sửa đổi truy cập hiện tại (C # 7.2). Hy vọng lược đồ giúp ghi nhớ dễ dàng hơn
(nhấp vào hình ảnh để xem tương tác.)
Nếu bạn đấu tranh để nhớ các công cụ sửa đổi truy cập hai từ, hãy nhớ bên ngoài - bên trong .
Hừm.
Xem tại đây: Bộ điều chỉnh truy cập .
Tóm lại:
Công khai cung cấp phương thức hoặc kiểu hiển thị đầy đủ từ các loại / lớp khác.
Riêng tư chỉ cho phép kiểu chứa phương thức riêng / truy cập biến vào phương thức / biến riêng (lưu ý rằng các lớp lồng nhau cũng có quyền truy cập vào các lớp / phương thức riêng của lớp chứa).
Được bảo vệ tương tự như riêng tư ngoại trừ các lớp dẫn xuất cũng có thể truy cập các phương thức được bảo vệ.
"Không có gì" là VB.NET tương đương với null. Mặc dù nếu bạn đang đề cập đến "nothing" có nghĩa là "không có công cụ sửa đổi truy cập", thì điều đó còn tùy thuộc, mặc dù một quy tắc rất thô sơ (chắc chắn trong C #) là nếu bạn không chỉ định rõ ràng công cụ sửa đổi truy cập, thì phương thức / biến khai báo thường là hạn chế như nó có thể được. I E
public class MyClass
{
string s = "";
}
có hiệu quả tương tự như:
public class MyClass
{
private string s = "";
}
Bài viết MSDN được liên kết sẽ cung cấp một mô tả đầy đủ khi không có công cụ sửa đổi truy cập được chỉ định rõ ràng.
công cộng - có thể được truy cập bởi bất cứ ai ở bất cứ đâu.
private - chỉ có thể được truy cập từ trong với nó, nó là một phần của.
được bảo vệ - chỉ có thể được truy cập từ trong trong lớp hoặc bất kỳ đối tượng nào kế thừa khỏi lớp.
Không có gì giống như null nhưng trong VB.
Tĩnh có nghĩa là bạn có một thể hiện của đối tượng đó, phương thức cho mọi thể hiện của lớp đó.
Ừm ...
Tĩnh có nghĩa là bạn có thể truy cập hàm đó mà không cần có một thể hiện của lớp.
Bạn có thể truy cập trực tiếp từ định nghĩa lớp.
Một trạng thái của Private chỉ ra rằng các biến chỉ có thể được truy cập bởi các đối tượng của cùng một lớp. Tình trạng được bảo vệ mở rộng quyền truy cập để bao gồm cả hậu duệ của lớp.
"từ bảng trên, chúng ta có thể thấy sự trì hoãn giữa riêng tư và được bảo vệ ... tôi nghĩ cả hai đều giống nhau .... vì vậy cần gì cho hai lệnh riêng biệt đó"
Kiểm tra liên kết MSDN để biết thêm thông tin
Những sửa đổi truy cập xác định nơi các thành viên của bạn được nhìn thấy. Bạn có lẽ nên đọc nó lên. Lấy liên kết được đưa ra bởi IainMH làm điểm bắt đầu.
Các thành viên tĩnh là một cho mỗi lớp và không phải là một ví dụ.
Cẩn thận xem khả năng tiếp cận của các lớp học của bạn. Các lớp và phương thức công khai và được bảo vệ theo mặc định có thể truy cập được cho mọi người.
Ngoài ra, Microsoft không quá phô trương trong việc hiển thị các sửa đổi truy cập (từ khóa công khai, được bảo vệ, v.v.) khi các lớp mới trong Visual Studio được tạo. Vì vậy, hãy chăm sóc cẩn thận và suy nghĩ về khả năng tiếp cận của lớp bạn vì đó là cánh cửa cho các bộ phận thực hiện của bạn.
Tôi nghĩ rằng nó có liên quan đến thiết kế OOP tốt. Nếu bạn là nhà phát triển thư viện, bạn muốn ẩn hoạt động bên trong của thư viện. Bằng cách đó, bạn có thể sửa đổi hoạt động bên trong thư viện của mình sau này. Vì vậy, bạn đặt các thành viên và phương thức trợ giúp của mình ở chế độ riêng tư và chỉ các phương thức giao diện là công khai. Các phương pháp nên được ghi đè nên được bảo vệ.
C # có tổng cộng 6 công cụ sửa đổi truy cập:
private : Thành viên được khai báo với khả năng truy cập này có thể hiển thị trong loại có chứa, nó không hiển thị với bất kỳ loại dẫn xuất nào, các loại khác trong cùng một cụm hoặc các loại bên ngoài lắp ráp có chứa. tức là, truy cập chỉ giới hạn ở loại chứa.
được bảo vệ : Thành viên được khai báo với khả năng truy cập này có thể được nhìn thấy trong các loại có nguồn gốc từ loại có chứa trong cụm chứa và các loại có nguồn gốc từ loại có chứa bên ngoài lắp ráp có chứa. tức là, truy cập bị giới hạn trong các loại dẫn xuất của loại chứa.
bên trong : Thành viên được khai báo với khả năng truy cập này có thể được nhìn thấy trong hội đồng có chứa thành viên này, nó không thể nhìn thấy đối với bất kỳ hội đồng nào bên ngoài tổ hợp có chứa. tức là, truy cập chỉ giới hạn trong việc chứa lắp ráp.
bảo vệ bên trong : Thành viên được khai báo với khả năng truy cập này có thể hiển thị trong các loại có nguồn gốc từ loại có chứa bên trong hoặc bên ngoài cụm chứa, nó cũng hiển thị với bất kỳ loại nào trong cụm chứa. tức là, truy cập bị giới hạn trong việc chứa các kiểu lắp ráp hoặc dẫn xuất.
công cộng : Thành viên được khai báo với khả năng truy cập này có thể hiển thị trong hội đồng có chứa thành viên này hoặc bất kỳ hội đồng nào khác tham chiếu đến tổ hợp có chứa. tức là truy cập không giới hạn.
C # 7.2 đang thêm một cấp độ tiếp cận mới:
bảo vệ riêng tư : Thành viên được khai báo với khả năng truy cập này có thể được nhìn thấy trong các loại có nguồn gốc từ loại có chứa này trong hội đồng chứa. Nó không thể nhìn thấy đối với bất kỳ loại không xuất phát từ loại có chứa, hoặc bên ngoài lắp ráp có chứa. tức là, quyền truy cập bị giới hạn ở các loại dẫn xuất trong cụm chứa.
Nguồn bao gồm mã mẫu của công cụ sửa đổi truy cập được bảo vệ riêng tư mới