Sunday, May 11, 2008

Access modifiers

.Net assemblies


Before we dive into access modifiers we need first to define .Net assemblies. A .Net assembly is an IL (Intermediate Language) code library, this definition includes both process assemblies (exe) and library assemblies (dll).


Access modifiers are keywords used to specify the declared accessibility of a member or a type. The significance of access modifiers comes from their use of defining a type's interfaces (the parts of the type exposed to other types, see the Encapsulation post). A type can be a class, a struct, an interface ... . Access modifiers keywords are:

  • private
  • protected
  • public
  • internal
C# keywordMeaning
privateaccessible only to this type
protectedaccessible only to this type and derived types (even outside the assembly)
internalaccessible to all classes within the same assembly
protected internalaccessible only to this type and derived types within the assembly
publicunrestricted


The private keyword

A member marked with the private keyword means it's only accessible to this type. Only other members of the type can access it.
The private keyword is used to hide both the data and the methods of the inner implementation of the type.


The protected keyword

A member marked with the protected keyword means it's accessible only to this type and derived types (inside or outside the assembly). The private keyword shapes the protected interface of the type (the parts of the type that is exposed to derived types).


class A
{
    protected int x;
}

class B : A
{
    // x is visible here because it's a protected member of the base class. x is still protected and it became a member of this class
}

class C : B
{
    // x is visible here because it's a protected member of the base class. x here is still protected
}

class D // doesn't inherit from any any class
{
    A ref_a = new A();

    // ref_a.x is not accessible from here because D doesn't inherits from A, B or C
}


The internal keyword

A member marked with the internal keyword means it's accessible to all other types located only in the same assembly. If you reference this assembly from somewhere else, you wont be able to access internal or protected internal members because they are public or protected at the assembly level.


protected internal

A member marked with the protected internal combination means it's both protected AND internal that is it's accessible only to derived types located only in the same assembly.


The public keyword

A member marked with the public keyword means it's accessible to any other type (inside or outside the assembly).
The public keyword is used to define the public interface of the type (the parts of the type that is exposed to any other type).


Nested types


A nested class is a class that is defined within another class. You sometimes nest classes to organize them or to expose the outer class's private and protected members to the nested class. A nested class can be thought of as a member of the containing class although it's not. What I mean is you can have a private class inside another class so this nested class is only accessible to the class containing it.


class A
{
    private int x;
    ...
    class B
    {
        // we can access A's x from here. in fact, we can access all the members of A
    }
    ...
}


You access nested classes the way you access members. you write A.B to access the class B from out side the class A if the class B was part of the public interface or the protected interface.


You can not make the outer class inherit from any of its inner classes. You can not do something like class A : A.B


Remarks


  • The default access level of classes and structs is private and the default access level of enums and interfaces is public.

  • Once you declare a member with a specific access level you cannot change its access level in derived types.

  • There are some restrictions on the use of access modifiers. For example, you can not have a private class A and a public class B that inherits A. Because the base class must be at least as accessible as the child class otherwise it wouldn't make any sense. The same rule is applied with function return types and function parameters. You can find more about Restrictions on Using Accessibility Levels here.

  • Members of enums and interfaces can not be marked with access modifiers. While the members of a struct can be marked only with public, internal or private.



Again this codeproject article by Marc Clifton.
And access modifiers at the MSDN.

I want to thank all my teachers and everyone who support me specially my teacher Mohamed Samy for his efforts and vision during the preparation of the previous couple posts.

4 comments:

saz said...

Special thanks to Dr Mohamed Samy as well as to you.
But I just couldn't understand what does it mean to "be defined within(inside or outside) the same assembly"

Eslam Afifi said...

A .Net assembly is the IL code the compiler generates. It can be an exe or dll. It can be generated in memory or written to file.

Anyway, there are two scopes when dealing with an assembly. From inside the assembly and from outside the assembly. When you're writing the code of the assembly and when you're referencing to the assembly in another code.

What I mean is that there is the scope where Microsoft guys were writing the library that generated System.dll and the scope which you reference to the System.dll and write using System; and start using the types in it.

Now, the keyword internal specify that this type class/struct/interface/enum/... is only to be used when writing the code of the assembly (writing the library of System.dll) and any code that reference the assembly is not to deal with this type.

Suppose there is a class xyz located in the "System" code
internal class xyz
{
....
}

Maybe the System.String class is using it in its implementation but you don't deal with the xyz when you reference the System.dll as you deal with System.String


I hope I could help :)

saz said...

Thanks alot

Eslam Afifi said...

You're welcome