Website development and design blog, tutorials and inspiration

C# Access Modifiers and Scope

C# Access Modifiers and Scope

By , 19th May 2007 in C#

In almost all programming languages you will see variables, methods and objects prefixed with either public, private, protected or internal. C# is no different and this guide will show you what they mean and how to use them.
 

These keywords are called Access Modifiers, and they define the scope of the object, that is who or what can see it.

Private scope means that it can only be accessed from the current scope - that is if the code is in a method, only that method can see the object. If the code is in a class, then only that class can see it.

Public scope means that it is freely visible by everyone and everything.

Protected scope means that only the class or derived classes can see it.

When declaring objects, by default there is no scope defined and all objects are created with the private scope. In the following example, both lines perform the same declaration of a private integer.

  1. int x;
  2. private int x;

Let's look at a simple demo class, and investigate the difference between public and private objects.

  1. public class Demo
  2. {
  3. private int x;
  4. public int y;
  5.  
  6. public void Demo()
  7. {
  8. x = 1;
  9. y = 2;
  10. }
  11.  
  12. public myFunction(int x)
  13. {
  14. Console.WriteLine(x);
  15. }
  16. }
  17.  
  18. class Program
  19. {
  20. static void Main()
  21. {
  22. Demo demo1 = new Demo();
  23. Console.WriteLine(demo1.x); // Error Here
  24. Console.WriteLine(demo1.y);
  25. }
  26. }

When you try and compile this code, the compiler will fail and show an error: "Demo.x is not accessible due to its protection level". This is because x has been declared as a private variable of the Demo class. It is however accessible from within the Demo class.

What do you think would be the result if we called myFunction from within Main()?

  1. myFunction(10);

Would it output 1 or 10?

Local variables or method parameters take priority over other all other scope levels, so the method will output the value of x as passed in as a parameter, i.e. 10.

If you need to access the value of x declared as a field of the class you can use the this keyword. The keyword this is a reference to the current object's instance.

  1. public myFunction(int x)
  2. {
  3. Console.WriteLine(x); // Outputs 10
  4. Console.WriteLine(this.x); // Outputs 1
  5. }
  6.  

How about this example? What do you think the outcome would be if this code were compiled and ran?

  1. public class Demo
  2. {
  3. private int x;
  4. public int y;
  5.  
  6. public void Test()
  7. {
  8. int myInt = 1;
  9. }
  10. }
  11.  
  12. class Program
  13. {
  14. static void Main()
  15. {
  16. Console.WriteLine(Demo.myInt);
  17. }
  18. }

Will this work? No. The variable myInt only exists for the lifecycle of the Test method. myInt does not exist until Test is called, and myInt is destroyed when the Test method exits.

There are two other lesser used access modifiers called protected and internal. Protected objects are only accessible from within the class or another class that inherits from it. Internal objects are only available from within the compilation unit (assembly, dll or application).

If you are not familiar with inheritance, you may wish to read through the class inheritance tutorial before continuing.

Going back to the original Demo class, let's have a look at the protected access modifier. I have added a protected integer called z to help illustrate the access modifier.

  1. public class Demo
  2. {
  3. private int x;
  4. public int y;
  5. protected int z;
  6.  
  7. public void Demo()
  8. {
  9. x = 1;
  10. y = 2;
  11. z = 3;
  12. }
  13. }
  14.  
  15. public class AnotherSampleDemo : Demo
  16. {
  17. public void AnotherSampleDemo()
  18. {
  19. x = 100;
  20. y = 1000;
  21. z = 10000;
  22. }
  23. }
  24.  
  25. class Program
  26. {
  27. static void Main()
  28. {
  29. Demo demo1 = new Demo();
  30. Console.WriteLine(demo1.x);
  31. Console.WriteLine(demo1.y);
  32. Console.WriteLine(demo1.z);
  33. }
  34. }

When compiling this code, there will be two errors. Firstly, the Program class cannot access the private integer x, nor can it access the protected integer z. The second error is that the AnotherSampleDemo, although inherited from Demo class, does not have access to the private integer x, but it does have access to the protected integer z. This allows the Demo class to retain control over internal variables.

In real world applications, you should always encapsulate all variables with a property instead of giving access directly to the variable itself. You can read more about encapsulation here.

Comments

There are no comments for this post. Be the first!

Leave a Reply

Your email address will not be published.