8

If I have a class with a method I want protected and internal. I want that only derived classes in the assembly would be able to call it.

Since protected internal means protected or internal, you have to make a choice. What do you choose in this case - protected or internal?

brickner
  • 6,595
  • 3
  • 41
  • 54

5 Answers5

6

Personally I would choose protected. If subclasses in your own assembly are good enough to call the method, why wouldn't a subclass in another assembly? Perhaps you could refactor the functionality into a separate (internal) class altogether.

You really need to think objectively about the purpose of the method. Internal accessibility almost always feels wrong to me. Mostly because of my experience trying to derive from controls or classes in the .NET framework where I ran into a brick wall because someone decided to mark a class or method as internal. The original author never noticed that not having access to that method made things much harder to implement a subclass.

EDIT

To clarify, internal accessibility for a class is very useful and I wasn't implying internal in general is bad. My point was that internal methods on an otherwise public class seems wrong to me. A properly designed base class should not give an unfair advantage to derived classes in the same assembly.

Josh
  • 68,005
  • 14
  • 144
  • 156
  • How about cases where you have reflection on the assembly classes and if the subclass won't get reflected (because it's outside of the assembly), this method won't work right? – brickner May 20 '10 at 05:43
  • Easy question. I never had to use reflection either `:)` – Kobi May 20 '10 at 05:45
  • 1
    @Kobi, you never use attributes? – brickner May 20 '10 at 06:02
  • -1 You're doing it wrong. If you're writing an API, and you're creating classes that only apply to the internals of the assembly (helper/utility classes) you definitely don't want users deriving from those classes. If you let them, they'll write code that adds dependencies to the internal implementation (making it impossible to change in the future without pissing of your users). Everything, I repeat everything that you don't design explicitly for your users to access should be marked with internal or private. – Evan Plaice Feb 28 '11 at 12:23
  • (cont) To not do so only gives users more ways to hack your library in un-intended ways making it more difficult to support. Plus, to effectively document an API, everything marked public (in an ideal world) should be commented properly. There's a good reason that some parts of .NET framework don't give you access. – Evan Plaice Feb 28 '11 at 12:23
  • @Evan, I'm fine with internal classes. I use them regularly. In the OP's example, he implied a public unsealed class with a hypothetical protected+internal method. If subclasses within the same assembly have access to the method, so should subclasses outside of the assembly. – Josh Mar 01 '11 at 06:35
  • @Josh Ok... I reverse that to a +1. Although, I don't see the point of making the method internal if you wanted it to be accessible outside of the assembly. In this case I think LBushkin's comment hits the nail on the head (as long as the class doesn't contain methods/members that are designed to be publicly accessible). Interesting food for thought. – Evan Plaice Mar 17 '11 at 11:48
5

I want that only derived classes in the assembly would be able to call it.

Well then, you have two choices. You can make it protected, and whenever one of your customers extends your class and calls your method and you find out about it, you can write them a sternly worded letter telling them to please stop doing that. Or you can make it internal, and do code reviews of your coworkers' code to ensure that they don't use the method they're not supposed to use.

My guess is that the latter is the cheaper and easier thing to do. I'd make it internal.

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • 3
    **There is possibly a third choice.** The OP could make the *entire class* internal, in which case `protected` access on the method would achieve the desired behavior. Code outside of the assembly could access the class' functionality through a public interface. That may be sufficient to achieve the OP's desired behavior. The disadvantage, of course, is that all inheritance outside of the assembly would be prohibited ... but the OP does explicitly not indicate that is a requirement. – LBushkin May 20 '10 at 13:23
3

I believe the right choice is internal. This way you can protect people outside of your assembly from calling this method, and this only leaves you to be careful and only call this method from derived classes. It is easier to be careful in the assembly you write than hope other people would be careful when they use it.

brickner
  • 6,595
  • 3
  • 41
  • 54
  • 2
    More information here: http://blogs.msdn.com/ericlippert/archive/2008/04/24/why-can-t-i-access-a-protected-member-from-a-derived-class-part-three.aspx – Dean Harding May 20 '10 at 05:02
1

It's such a quirky decision to make protected internal mean protected OR internal. For this precise case I would use internal. The reason is that if encapsulation is broken, I would rather it'd be me, rather that someone not under my control.

Igor Zevaka
  • 74,528
  • 26
  • 112
  • 128
0

I think the answer varies based on your needs. If I were you, I would do something like this:

    public class YourClass
    {
       protected class InnerClass
       {
           internal void YourMethod()
           {
               // Your Code
           }
       }
    }
Matin Habibi
  • 700
  • 1
  • 8
  • 20