Supervised by:D.Saman n this article, we are going to explain different types of access modifiers in C# and what their purpose is.
For the complete navigation of this series
check out: C# Back to Basics. Access modifiers specify the accessibility of an object and all of its members in the C# project. Moreover, all the C# types have access modifiers implemented, even if they are not stated (default access modifier is applied then).
Even though this topic is more related to
the object-oriented concept, we will talk about it now, thus making it easier to understand the next article about methods, that strongly relies on access modifiers Access Modifiers Types C# provides four types of access modifiers: private, public, protected, internal, and two combinations: protected-internal and private-protected.
Private Access Modifier
Objects that implement private access modifiers are accessible only inside a class or a structure. As a result, we can’t access them outside the class they are created: class NumberClass { private int number = 10; } class Program { static void Main(string[] args) { NumberClass num = new NumberClass(); Console.WriteLine(num.number); // Error. We can't access the number variable because // it has the private access modifier and its only accessible in the NumberClass class } } Public Access Modifier Objects that implement public access modifiers are accessible from everywhere in our project. Therefore, there are no accessibility restrictions: class NumberClass { public int number = 10; } class Program { static void Main(string[] args) { NumberClass num = new NumberClass(); Console.WriteLine(num.number); // This is OK. The number variable has the public access modifier. } } Protected Access Modifier The protected keyword implies that the object is accessible inside the class and in all classes that derive from that class. We will talk in more detail about inheritance in module 2 about object-oriented programming. But for now, we are going to take a look at this example to understand the behavior of the protected members: class NumberClass { protected int number = 10; //we can access this variable inside this class } class DerivedClass: NumberClass //this is inheritance. DerivedClass derives from the NumberClass class { void Print() { Console.WriteLine(number); //we can access it in this class as well because it derives from the NumberClass class } } class Program { void Print() { NumberClass num = new NumberClass(); Console.WriteLine(num.number); // Error. The number variable is inaccessible due to its protection level. // The Program class doesn't derive from the NumberClass } } Internal Access Modifier The internal keyword specifies that the object is accessible only inside its own assembly but not in other assemblies: //First Project (ASSEMBLY) public class NumberClassInFirstProject { internal int number = 10; //we can access this variable inside this class } class ProgramInFirstProject { void Print() { NumberClassInFirstProject num = new NumberClassInFirstProject(); Console.WriteLine(num.number); // This is OK. Anywhere in this project (assembly) // we can access the number variable. } } //Second project (ASSEMBLY) class Program { void Print() { NumberClassInFirstProject num = new NumberClassInFirstProject(); Console.WriteLine(num.number); // Error. The number variable is inaccessible due to its protection level. //The Program class in second project can't access the internal members from another project } } Protected Internal Access Modifier The protected internal access modifier is a combination of protected and internal. As a result, we can access the protected internal member only in the same assembly or in a derived class in other assemblies (projects): //First Project (ASSEMBLY) public class NumberClassInFirstProject { protected internal int number = 10; //we can access this variable inside this class } class ProgramInFirstProject { void Print() { NumberClassInFirstProject num = new NumberClassInFirstProject(); Console.WriteLine(num.number); // This is OK. Anywhere in this project (assembly) we can access the number variable. } } //Second project (ASSEMBLY) class Program: NumberClassInFirstProject //Inheritance { void Print() { Console.WriteLine(number); //This is OK as well. The class Program derives from the NumberClassInFirstProject clas. } } Private Protected Access Modifier The private protected access modifier is a combination of private and protected keywords. We can access members inside the containing class or in a class that derives from a containing class, but only in the same assembly(project). Therefore, if we try to access it from another assembly, we will get an error. Conclusion So, that’s it about access modifiers. As a result, we have learned what types of access modifiers we can use in C# and what are the limitations of them.
Our next topic is going to be about Methods
in C#.
All types and type members have an
accessibility level. The accessibility level controls whether they can be used from other code in your assembly or other assemblies. An assembly is a .dll or .exe created by compiling one or more .cs files in a single compilation. Use the following access modifiers to specify the accessibility of a type or member when you declare it: public: The type or member can be accessed by any other code in the same assembly or another assembly that references it. The accessibility level of public members of a type is controlled by the accessibility level of the type itself. private: The type or member can be accessed only by code in the same class or struct. protected: The type or member can be accessed only by code in the same class, or in a class that is derived from that class. internal: The type or member can be accessed by any code in the same assembly, but not from another assembly. In other words, internal types or members can be accessed from code that is part of the same compilation. protected internal: The type or member can be accessed by any code in the assembly in which it's declared, or from within a derived class in another assembly. private protected: The type or member can be accessed by types derived from the class that are declared within its containing assembly. Class, record, and struct accessibility Classes, records, and structs declared directly within a namespace (in other words, that aren't nested within other classes or structs) can be either public or internal. internal is the default if no access modifier is specified. Struct members, including nested classes and structs, can be declared public, internal, or private. Class members, including nested classes and structs, can be public, protected internal, protected, internal, private protected, or private. Class and struct members, including nested classes and structs, have private access by default. Private nested types aren't accessible from outside the containing type. Derived classes and derived records can't have greater accessibility than their base types. You can't declare a public class B that derives from an internal class A. If allowed, it would have the effect of making A public, because all protected or internal members of A are accessible from the derived class. You can enable specific other assemblies to access your internal types by using the InternalsVisibleToAttribute. For more information, see Friend Assemblies. Class, record, and struct member accessibility Class and record members (including nested classes, records and structs) can be declared with any of the six types of access. Struct members can't be declared as protected, protected internal, or private protected because structs don't support inheritance. Normally, the accessibility of a member isn't greater than the accessibility of the type that contains it. However, a public member of an internal class might be accessible from outside the assembly if the member implements interface methods or overrides virtual methods that are defined in a public base class. The type of any member field, property, or event must be at least as accessible as the member itself. Similarly, the return type and the parameter types of any method, indexer, or delegate must be at least as accessible as the member itself. For example, you can't have a public method M that returns a class C unless C is also public. Likewise, you can't have a protected property of type A if A is declared as private. User-defined operators must always be declared as public and static. For more information, see Operator overloading. Finalizers can't have accessibility modifiers. To set the access level for a class, record, or struct member, add the appropriate keyword to the member declaration, as shown in the following example.