views:

105

answers:

6

When defining a class as internal, do you define what would usually be public fields as internal? Or do you leave them as public? I have a set of classes with public/private methods that I have decided to set as internal. Now, should I change the class' modifier to internal and let the rest of the methods/properties as they are (public/private) or switch them to (internal/private)?

I don't see a big point in changing it to internal, and if by some reason later I want to set them back to public it's going to give a lot of work to have to put them back to public again.

Any other thoughts on this?

+6  A: 

I can't see any reason not to leave them as public, as your class won't be visible to outside assemblies anyway. The only case where I think this might matter is when using reflection over that class.

Johannes Rudolph
+1  A: 

You defnitely shouldn't change private members to internal as that would make them more accessible. There is no need to change public members to internal since nothing outside of the defining assembly will ever be able to get a reference to an internal class anyway.

Daniel Renshaw
+2  A: 

If I have a class that is internal, I leave the class members as public (or protected/private of course if that's what they were). I find that often I have classes that I hope I can keep internal that I end up having to expose eventually and switching all the appropriate members back to public is annoying.

jkohlhepp
+1  A: 

I think you should give generally members the same visibility as you would if the Type were itself public.

That is, members that are part of the public API should be public, and members that are special-purpose helpers that should only be visible to "friend" classes should be internal.

This means there will be no changes to member visibility if you ever decide to make the Type public.

More importantly, it also documents your intention - anyone reading your code will be able to identify which (if any) members are intended to be internal.

Joe
A: 

We use internal keyword for members in internal classes, so that the intention is clear. However it fails if one implicitly implement internal interfaces, where the members have to be defined as public. We dont know why and see this as an accidental mistake in the language specification that we have to live with.

Janko R
A: 

Dig around in Reflector for a bit and you'll see that the BCL itself is wildly inconsistent over this. You'll see many internal classes with public members and many others with internal members. Several classes even mix and match the two with no particular rhyme or reason that I'm able to discern.

There is no "right" answer here, but there are a few things you should consider whenever you need to make a decision on this:

  • internal members cannot implicitly implement an interface, and explicit implementations are always private. So if you want interface members to be accessible through the class instance (the Dispose method of IDisposable is a common one), they need to be public.

  • Type visibilities can change. You might decide down the road that an internal class has some valuable functionality that you want to make available to the outside. But if you do, then all public members become accessible by everyone. You should decide in advance if this is what you want.

  • On the other hand, another reason you might make an internal class public is if you decide that you need to subclass it and that the derived classes should be in a different assembly. In this case, some of your internal members should probably be protected internal instead, otherwise derived classes won't have access to members they might need.

In the end, what it all comes down to is writing code to be read and maintained by other people. The modifier internal can mean two very different things to a maintenance programmer:

  1. That it doesn't seem useful to the outside world, but wouldn't actually be harmful either. A typical example would be a utility class that was whipped up in 5 minutes and doesn't do much validation or error checking. In this case, it's OK for someone to make it public as long as they tighten up the code a little and/or document how to use it properly. Make this assumption explicit by making the members public.

  2. That it's actually not safe for outside consumption; it might manipulate some protected state, leave handles or transactions open, etc. In this case, you really want to make the individual methods internal to make it absolutely clear that nobody else should be using this class, ever.

Choose whichever one is appropriate for your scenario.

Aaronaught