Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

internal protected property still accessible from a different assembly

Tags:

c#

.net

I'm setting up some demo code for a beginner session on accessibility and I found that I am able to access an internal protected property from a derived class. What am I missing?

Assembly 1

namespace Accessibility
{
    class Program
    {
        static void Main(string[] args)
        {
            ExampleClass c = new ExampleClass();
            c.Go();
            //c.Prop1 = 10;
        }
    }

    class ExampleClass : DerivedClass
    {
        public void Go()
        {
            this.Prop1 = 10;
            this.Prop2 = 10;
            //this.Prop3 = 10; //Doesn't work
            //this.Prop4 = 10; //Doesn't work
            this.Prop5 = 10; //why does this work?!

            this.DoSomething();
        }
    }
}

Assembly 2

namespace Accessibility.Models
{
    public class BaseClass
    {
        public int Prop1 { get; set; }
        protected int Prop2 { get; set; }
        private int Prop3 { get; set; }

        internal int Prop4 { get; set; }
        internal protected int Prop5 { get; set; }
        //internal public int Prop6 { get; set; } //Invalid 
        //internal private int Prop7 { get; set; } //Invalid

        public BaseClass()
        {
            this.Prop3 = 27;
        }
    }

    public class DerivedClass : BaseClass
    {
        public void DoSomething()
        {
            this.Prop1 = 10;
            this.Prop2 = 10;
            //this.Prop3 = 10; //Doesn't work
            this.Prop4 = 10;
            this.Prop5 = 10;

            PropertyInfo Prop3pi = typeof(DerivedClass).GetProperty("Prop3", BindingFlags.Instance | BindingFlags.NonPublic);
            int value = (int)Prop3pi.GetValue(this, null);
        }
    }
}

Notice in ExampleClass.Go I can set a value to Prop5. Why? It's marked as internal protected but I can't set a value on Prop4 (marked as internal)

like image 818
Dustin Davis Avatar asked Aug 09 '11 18:08

Dustin Davis


People also ask

Can we access protected member outside assembly in C#?

Introduction to Private Protected in C# Private members are restricted to the class and cannot be accessed outside that class even by creating its object.

Which of the following is true about the accessibility modifier protected internal?

- It is available to classes that are within the same assembly or derived from the specified base class. CORRECT ANSWER : It is available to classes that are within the same assembly or derived from the specified base class.

Who can access protected internal?

A protected internal member is accessible from the current assembly or from types that are derived from the containing class. For a comparison of protected internal with the other access modifiers, see Accessibility Levels.

What's the difference between protected and internal What about protected internal?

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.


2 Answers

internal protected means "internal to the assembly OR an inherited class". So yes, if you have a public class with an protected internal member, another class that inherits that type in a different assembly can still access it because of the protected modifier:

protected internal

The type or member can be accessed by any code in the assembly in which it is declared, or from within a derived class in another assembly. Access from another assembly must take place within a class declaration that derives from the class in which the protected internal element is declared, and it must take place through an instance of the derived class type.

Reference: http://msdn.microsoft.com/en-us/library/ms173121.aspx

This is a limitation of the C# language. The CLR supports the "Internal AND Protected" notion. There is evidence of this with the MethodAttributes.FamANDAssem enumeration if you were emitting your own IL. If you really wanted this feature, you could do some IL post processing with something like Mono.Cecil. Why the C# language does not expose this is only a guess: little need for it.

like image 140
vcsjones Avatar answered Sep 20 '22 12:09

vcsjones


Because it's how internal protected is intended to work. Access is given for either children in inheritance tree (protected part) or for the same assembly (internal part) - see Access Modifiers on MSDN.

And your ExampleClass is in the inheritance tree of BaseClass, which defines Prop5. So the access is thanks to protected part.

like image 29
NOtherDev Avatar answered Sep 18 '22 12:09

NOtherDev