65.9K
CodeProject is changing. Read more.
Home

C# Access Modifiers Quick Reference

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.58/5 (27 votes)

Apr 9, 2008

CPOL

1 min read

viewsIcon

101218

downloadIcon

890

A quick description of access modifiers with a diagram showing accessibility limits

IllustrateAccessInCsharp2.png

Introduction

This is a very small article to illustrate C# access modifiers. This article is for beginners but even if you are an expert, this article may be useful as a quick reminder when the brain cells slow down - hey, I will probably need it soon.

Definition

An access modifier is a keyword you can add to your declaration of a class or class member to allow or restrict their accessibility.

The diagram above illustrates how each access modifier affects the accessibility of the class or member.

Using the Code

I kind of doubt you will need any more than the diagram as a reminder, but since I want to make this article more complete for beginners, here is some more content.

Now, a few examples:

    internal class Class1
    {
        private int Member1;
        protected int Member2;
        internal int Member3;
        protected internal int Member4;

        private class NestedClass
        {
            void Test(Class1 foo)
            {
                foo.Member1 = 0; //OK
                foo.Member2 = 0; //OK
                foo.Member3 = 0; //OK
                foo.Member4 = 0; //OK
            }
        }
    }

    public class Class2
    {
        private void Method1()
        {
        }

        private int _Member1;

        protected int Member1
        {
            get
            {
                return _Member1;
            }
            set
            {
                Method1();
                _Member1 = value;
            }
        }

        internal int Member2;
        public int Member3;
        protected internal int Member4;
    }

The above access modifiers prevent direct access as seen by the following access attempts. These attempts produce compilation errors:

From the same assembly as the above classes:

    class Test
    {
        void Test1()
        {
            Class1 c1 = new Class1(); //OK
            c1.Member1 = 0; //Compilation error here
            c1.Member2 = 0; //Compilation error here
            c1.Member3 = 0; //OK
            c1.Member4 = 0; //OK
        }
    }

    internal class DerivedClass : Class1
    {
        private void Test2()
        {
            Member1 = 0; //Compilation error here
            Member2 = 0; //OK
            Member3 = 0; //OK
            Member4 = 0; //OK
        }

        private class NestedClass
        {
            void Test(DerivedClass foo)
            {
                foo.Member1 = 0; //Compilation error here
                foo.Member2 = 0; //OK
                foo.Member3 = 0; //OK
                foo.Member4 = 0; //OK
            }
            void Test(Class1 foo)
            {
                foo.Member1 = 0; //Compilation error here
                foo.Member2 = 0; //Compilation error here
                foo.Member3 = 0; //OK
                foo.Member4 = 0; //OK
            }
        }
    }

From a different assembly from the above classes:

    public class Test
    {
        void Test1()
        {
            Class1 c1 = new Class1(); //Compilation error here

            Class2 c2 = new Class2(); //OK
            c2.Method1(); //Compilation error here
            c2._Member1 = 0; //Compilation error here
            c2.Member1 = 0; //Compilation error here
            c2.Member2 = 0; //Compilation error here
            c2.Member3 = 0; //OK
            c2.Member4 = 0; //Compilation error here
        }
    }

    internal class DerivedClass : Class2
    {
        private void Test2()
        {
            Member1 = 0; //OK
            Member2 = 0; //Compilation error here
            Member3 = 0; //OK
            Member4 = 0; //OK
        }
        private class NestedClass
        {
            void Test(DerivedClass foo)
            {
                foo.Member1 = 0; //Compilation error here
                foo.Member2 = 0; //Compilation error here
                foo.Member3 = 0; //OK
                foo.Member4 = 0; //OK
            }
            void Test(Class2 foo)
            {
                foo.Member1 = 0; //Compilation error here
                foo.Member2 = 0; //Compilation error here
                foo.Member3 = 0; //OK
                foo.Member4 = 0; //Compilation error here
            }
        }
    }

Points of Interest

In the examples above, you restrict direct access to Class2._Member1 but provide a wrapped property called Member1. The requirement is to ensure Method1 is called when _Member1 changes. The access modifiers ensure that we can only change _Member1 via the property.

That concludes the article.

History

  • 9th April, 2008: Initial version
  • 10th April, 2008: Modified to include more detail
  • 14th April, 2008: Modified diagram