1800 INFORMATION
1800 INFORMATION

Reputation: 135285

Should I use internal or public visibility by default?

I'm a pretty new C# and .NET developer. I recently created an MMC snapin using C# and was gratified by how easy it was to do, especially after hearing a lot of horror stories by some other developers in my organisation about how hard it is to do in C++.

I pretty much went through the whole project at some point and made every instance of the "public" keyword to "internal", except as required by the runtime in order to run the snapin. What is your feeling on this, should you generally make classes and methods public or internal?

Upvotes: 44

Views: 17662

Answers (14)

Ryan Lundy
Ryan Lundy

Reputation: 210150

What you did is exactly what you should do; give your classes the most minimal visibility you can. Heck, if you want to really go whole hog, you can make everything internal (at most) and use the InternalsVisibleTo attribute, so that you can separate your functionality but still not expose it to the unknown outside world.

The only reason to make things public is that you're packaging your project in several DLLs and/or EXEs and (for whatever reason) you don't care to use InternalsVisibleTo, or you're creating a library for use by third parties. But even in a library for use by third parties, you should try to reduce the "surface area" wherever possible; the more classes you have available, the more confusing your library will be.

In C#, one good way to ensure you're using the minimum visibility possible is to leave off the visibility modifiers until you need them. Everything in C# defaults to the least visibility possible: internal for classes, and private for class members and inner classes.

Upvotes: 14

Ryan Farley
Ryan Farley

Reputation: 11431

Do not choose a "default". Pick what best fits the visibility needs for that particular class. When you choose a new class in Visual Studio, the template is created as:

class Class1
{
}

Which is private (since no scope is specified). It is up to you to specify scope for the class (or leave as private). There should be a reason to expose the class.

Upvotes: -1

ColinD
ColinD

Reputation: 110056

You should tend toward exposing as little as possible to other classes, and think carefully about what you do expose and why.

Upvotes: 1

Brownie
Brownie

Reputation: 7738

I think you should err on the side of internal classes and members. You can always increase an item's visibility but decreasing it can cause problems. This is especially true if you are building a framework for others.

You do need to be careful though not to hide useful functionality from your users. There are many useful methods in the .NET BCL that cannot be used without resorting to reflection. However, by hiding these methods, the surface area of what has to be tested and maintained is reduced.

Upvotes: 8

Aaron Murgatroyd
Aaron Murgatroyd

Reputation: 1546

You should try to make them only as visible as possible, but as stated by Mike above, this causes problems with UserControls and using the VS Designer with those controls on forms or other UserControls.

So as a general rule, keep all classes and UserControls that you aren't adding using the Designer only as visible as they need to be. But if you are creating a UserControl that you want to use in the Designer (even if that's within the same assembly), you will need to make sure that the UserControl class, its default constructor, and any properties and events, are made public for the designer to work with it.

I had a problem recently where the designer would keep removing the this.myControl = new MyControl() line from the InitializeComponent() method because the UserControl MyControl was marked as internal along with its constructor.

It's really a bug I think because even if they are marked as internal they still show up in the Toolbox to add in the Designer, either Microsoft needs to only show public controls with public constructors, or they need to make it work with internal controls as well.

Upvotes: 1

user3225726
user3225726

Reputation: 21

by default class is created as internal in c#: internal means: Access is limited to the current assembly.

see http://msdn.microsoft.com/en-us/library/0b0thckt.aspx

Good Article the defaults scope is internal: http://www.c-sharpcorner.com/UploadFile/84c85b/default-scope-of-a-C-Sharp-class/

Upvotes: 0

James
James

Reputation: 6113

Most classes should be internal, but most non-private members should be public.

The question you should ask about a member is "if the class were made public would I want to member the member to be exposed?". The answer is usually "yes (so public)" because classes without any accessible members are not much use! internal members do have a role; they are 'back-door access' meant only for close relatives that live in the same assembly.

Even if your class remains internal, it is nice to see which are front-door members and which are back-door. And if you ever change it to public you are not going to have to go back and think about which are which.

Upvotes: 2

Peder Rice
Peder Rice

Reputation: 1794

I completely disagree with the answers so far. I feel that internal is a horrid idea, preventing another assembly from inheriting your types, or even using your internal types should the need for a workaround come about.

Today, I had to use reflection in order to get to the internals of a System.Data.DataTable (I have to build a datatable lightning fast, without all of its checks), and I had to use reflection, since not a single type was available to me; they were all marked as internal.

Upvotes: 0

Mike
Mike

Reputation: 63

I found a problem using internal classes as much as possible. You cannot have methods, properties, fields, etc of that type (or parameter type or return type) more visible than internal. This leads to have constructors that are internal, as well as properties. This shouldn't be a problem, but as a matter of fact, when using Visual Studio and the xaml designer, there are problems. False positive errors are detected by the designer due to the fact that the methods are not public, user control properties seems not visible to the designer. I don't know if others have already fallen on such issues...

Upvotes: 1

Ash
Ash

Reputation: 62096

Is there any reason you need to use Internal instead of Private? You do realise that Internal has assembly level scope. In other words Internal classes/members are accessible to all classes in a multi-class assembly.

As some other answers have said, in general go for the highest level of encapsulation as possible (ie private) unless you actually need internal/protected/public.

Upvotes: 1

Jay Bazuzi
Jay Bazuzi

Reputation: 46506

I prefer to avoid marking classes as public unless I explicitly want my customer to consume them, and I am prepared to support them.

Instead of marking a class as internal, I leave the accessibility blank. This way, public stands out to the eye as something notable. (The exception, of course, is nested classes, which have to be marked if they are to be visible even in the same assembly.)

Upvotes: 4

Matt Blaine
Matt Blaine

Reputation: 1976

I like to expose things as little as possible. Private, protected, internal, public: give classes, variables, properties, and functions the least amount of visibility they need for everything to still work.

I'll bump something's visibility up that chain toward public only when there's a good reason to.

Upvotes: 0

Heath Borders
Heath Borders

Reputation: 32117

It depends on how much control you have over code that consumes it. In my Java development, I make all my stuff public final by default because getters are annoying. However, I also have the luxury of being able to change anything in my codebase whenever I want. In the past, when I've had to release code to consumers, I've always used private variables and getters.

Upvotes: 0

Stephen Wrighton
Stephen Wrighton

Reputation: 37819

I believe in blackboxes where possible. As a programmer, I want a well defined blackbox which I can easily drop into my systems, and have it work. I give it values, call the appropriate methods, and then get my results back out of it.

To that end, give me only the functionality that the class needs to expose to work.

Consider an elevator. To get it to go to a floor, I push a button. That's the public interface to the black box which activates all the functions needed to get the elevator to the desired floor.

Upvotes: 40

Related Questions