Java has four categories of protection access for methods and variables :
C# has five categories of protection access: [1]
Java's default (also known as package) accessibility is no longer there, and there is a new accessibility category based on the internal modifier in C#. Table 8.1 shows more information about C#'s accessibility options. Table 8.2 shows the applicable accessibility modifiers for the various types/ members in C#, together with their default accessibility if no accessibility modifier is specified in their declarations. Note that no access modifiers are allowed in the declaration of namespaces, interface members, and enumeration members “ although these types/ members do have a default implicit accessibility level. Table 8.1. Declared accessibility of C# type members and their meanings
Table 8.2. Applicable access modifiers for types and their members
Like JavaThe accessibility of a type member is established by both:
For example, a field declared as public in a class which has internal accessibility will not be accessible from another class written in a separate program. You must be able to have access to the class before you can access its members even though it may seem that a member's accessibility is less strict (more accessible) than its enclosing type. Both factors have to be considered when determining the final accessibility of a member. Unlike Java
8.1.1 Further examplesI have presented several examples below to illustrate the accessibility domain of a class member declared as internal and protected internal because these are the special accessibility levels not applicable in Java. Let's explore the internal accessibility modifier first. Study Source1.cs below: 1: // Source1.cs 2: 3: namespace NameSpace1{ 4: public class A{ 5: internal static int X; 6: protected internal static int Y; 7: public static int Z; 8: 9: static void DoThis(){ 10: X = 1; 11: } 12: 13: class NestedA{ 14: static void DoThis(){ 15: A.X = 1; 16: } 17: } 18: } 19: 20: class B{ 21: static void DoThis(){ 22: A.X = 1; 23: } 24: } 25: } 26: 27: namespace NameSpace2{ 28: internal class C{ 29: 30: public static int W; 31: 32: static void DoThis(){ 33: NameSpace1.A.X = 1; 34: } 35: } 36: } This program compiles properly. Remember to compile with the /target: library option if you are using csc.exe since there is no Main() method: c:\expt>csc /target:library Source1.cs In this program, the accessibility of the field X in class A of the NameSpace1 namespace (declared on line 5) is being tested on line 33. The program shows that NameSpace1.A.X is accessible from:
In fact, X is accessible from anywhere inside the same program (codes in the same source file). However, X is not accessible from another class defined in a separate source file regardless of whether that class is in the same namespace as A . The following program, Source2.cs , written in another source file demonstrates this. Remember to compile Source2.cs using the /reference option if you are using csc.exe so that it can find the classes you have just written in Source1.dll : c:\expt>csc /reference:Source1.dll /target:library Source2.cs 1: // Source2.cs 2: 3: using NameSpace1; 4: using NameSpace2; 5: 6: // default namespace 7: class D:A{ 8: static void DoThis() { 9: A.X = 1; // compilation error 10: } 11: } 12: 13: namespace NameSpace1 { 14: class E{ 15: static void DoThis() { 16: A.X = 1; // compilation error 17: } 18: } 19: } Compilation error: Source2.cs(9,5): error CS0122: 'NameSpace1.A.X' is inaccessible due to its protection level Source2.cs(16,7): error CS0122: 'NameSpace1.A.X' is inaccessible due to its protection level NameSpace1.A.X is only accessible to code written in Source1.cs only. Even a class in the same namespace (class E in Source2.cs ) cannot access it if it is in another program (source file). Having understood internal accessibility, let's try out protected internal . Line 6 of Source1.cs declares field Y as protected internal . This time, Y is accessible to a class in an external program which is a subclass of NameSpace1.A . I have modified Source2.cs to prove this point: 1: // Source2.cs 2: 3: using NameSpace1; 4: 5: namespace NameSpace3 { 6: class D:A{ // subclass 7: static void DoThis() { 8: A.Y = 1; // ok 9: } 10: } 11: class E{ // non-subclass 12: static void DoThis() { 13: A.Y = 1; // compilation error 14: } 15: } 16: } Compilation error: Source2.cs(13,7): error CS0122: 'NameSpace1.A.Y' is inaccessible due to its protection level Here, A.Y is accessible by a class in another program (source file) as long as that class is a subclass of NameSpace1.A . As a final note, notice that although both fields NameSpace1.A.Z and NameSpace2.C.W in Source1.cs (declared on lines 7 and 30 respectively) have been declared as public , their resultant accessibility is different because class A is a public class, while class C is an internal class. Because class C is internal, you cannot access the class from another program. So despite C.W being declared as public , it is inaccessible from a class written in, say, Source2.cs . On the other hand, A.Z is truly free for all to use. |