Geeks With Blogs
New Things I Learned

I was talking with my peer today, and she told me about the weird behavior of using 'protected internal' access modifier.  Using that modifier does NOT mean that the property/field is protected (can only be accessed by that class or derived classes) AND internal (if the derived class is in a different assembly that derived class won't be able to see that property/field).

It turns out to be an OR - (per msdn) - that property/field is now protected (can only be accessed by that class or derived classescan only be accessed by that class or derived classes) AND that property field is now available internally as public (property/field can be accessed publically by any class in that assembly - it's not treated as protected anymore in that assembly).

The following code becomes valid:

// Both BaseClass and OtherClass resides in the same assembly, say assy1.dll

public class BaseClass

{

   private int _value;

 

   protected internal int Value

   {

      get { return _value; }

      set { _value = value; }

   }

}

 

public class OtherClass

{

   public void Test()

   {

      BaseClass bc = new BaseClass();

      bc.Value = 5; // This is valid now

   }

}

In my mind, this doesn't make sense; why would it be treated as if it's protected OR internal?  Derived classes in other assemblies work as expected, as the following code shows:

// Both these classes are in the same assembly, say assy2.dll

public class SomeClass

{

   public void Test()

   {

      BaseClass bc = new BaseClass();

      bc.Value = 9; // This causes CS0122 but will go away if you have

                    // [assembly: InternalsVisibleTo("assy2.dll")]

   }

}

 

public class DerivedClass : BaseClass

{

   public void Test()

   {

      base.Value = 7;

   }

}

The DerivedClass works as expected, it can access base.Value since it is a protected property.  The Test method in SomeClass will error out during compilation.  However, if you use the InternalsVisibleToAttribute, it will work again, since it treats assy2.dll as if it belongs in the same assembly.

So, the above construct doesn't help to achieve a situation where you want:

  • a public base class defined in an infrastructure DLL
  • one of its property/field is protected (can't be accessed within non-derived classes in said infrastructure DLL)
  • derived classes in other assemblies can't access that property/field (limiting that property so it can only be accessed in the infrastructure DLL)

I'm somewhat disappointed with this revelation, because we actually have s design that would benefit from having this ability; we have a base class where we want its function to only be available to some derived classes in other assemblies, but not others (mostly for 3rd party consumers), and we thought we can make those functions to be protected and also make it internal - assemblies that need access to those function will be allowed using the InternalsVisibleToAttribute.  But it wasn't meant to be...

Posted on Wednesday, January 23, 2008 6:49 PM .NET | Back to top


Comments on this post: protected internal modifier weirdness

# re: protected internal modifier weirdness
Requesting Gravatar...
Interesting revelation - looks like the way .NET enforces the internal access modifier is by mkaing the code invisible to outside assemblies. Perhaps .NET needs one more access modifier to disallow access even when exposed via InternalsVisibleToAttribute.


As for your current problem, it looks like you may need to divide your code in your dll into two dlls - one that is truly internal and another that isn't (and can be exposed via InternalsVisibleToAttribute)

I would be interested to know how you solve your problem,

Jonathan Starr

BTW, I liked your Windows Live presentation last night.
Left by Jonathan Starr on Jan 29, 2008 11:22 AM

# re: protected internal modifier weirdness
Requesting Gravatar...
Well I do believe that 'protected internal' means that inherited classes can access the member in ANY assembly where the inherited or type lies. I used this for the plugin-system in our game engine. It allowed for me to let user created plug-ins access the members for full flexibility.

Each modifier for any member in C# is acted upon separately to define the behavior of each member or type.
Left by qczackf on Nov 30, 2009 5:05 PM

Your comment:
 (will show your gravatar)


Copyright © Muljadi Budiman | Powered by: GeeksWithBlogs.net