views:

218

answers:

5

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?

+3  A: 

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
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
+5  A: 

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.

Josh Einstein
+1 from me. I don't think I ever had to use `internal`.
Kobi
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
Easy question. I never had to use reflection either `:)`
Kobi
@Kobi, you never use attributes?
brickner
+1  A: 

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
A: 

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
+4  A: 

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
**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