Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I'm designing a set of APIs for some applications I'm working on. I want to keep the code style consistent in all the classes I write but I've found that there are a few inconsistencies that I'm introducing and I don't know what the best way to resolve them is.

My example here is specific to C# but this would apply to any language with similar mechanisms.

There are a few classes that I need for implementation purposes that I don't necessarily want to expose in the API so I make them internal whereever needed.

Generally what I would do is design the class as I normally would (e.g., make members public/protected/private where necessary) and change the visibility level of the class itself to internal. So I might have a few classes that look like this:

internal interface IMyItem
{
    ItemSet AddTo(ItemSet set);
}

internal class _SmallItem : IMyItem
{
    private readonly /* parameters */;
    public _SmallItem(/* small item parameters */) { /* ... */ }

    public ItemSet AddTo(ItemSet set) { /* ... */ }
}

internal abstract class _CompositeItem: IMyItem
{
    private readonly /* parameters */;
    public _CompositeItem(/* composite item parameters */) { /* ... */ }

    public abstract object UsefulInformation { get; }
    protected void HelperMethod(/* parameters */) { /* ... */ }
}

internal class _BigItem : _CompositeItem
{
    private readonly /* parameters */;
    public _BigItem(/* big item parameters */) { /* ... */ }

    public override object UsefulInformation
    {
        get { /* ... */ }
    }

    public ItemSet AddTo(ItemSet set) { /* ... */ }
}

In another generated class (part of a parser/scanner), there is a structure that contains fields for all possible values it can represent. The class generated is internal too but I have control over the visibility of the members and decided to make them internal as well.

internal partial struct ValueType
{
    internal string               String;
    internal ItemSet              ItemSet;
    internal IMyItem              MyItem;
}

internal class TokenValue
{
    internal static int EQ(ItemSetScanner scanner) { /* ... */ }
    internal static int NAME(ItemSetScanner scanner, string value) { /* ... */ }
    internal static int VALUE(ItemSetScanner scanner, string value) { /* ... */ }
    //...
}

To me, this feels odd because the first set of classes, I didn't necessarily have to make some members public, they very well could have been made internal. internal members of an internal type can only be accessed internally anyway so why make them public? I just don't like the idea that the way I write my classes has to change drastically (i.e., change all uses of public to internal) just because the class is internal.

Any thoughts on what I should do here?

It makes sense to me that I might want to make some members of a class declared public, internal. But it's less clear to me when the class is declared internal.

share|improve this question

migrated from codereview.stackexchange.com Feb 11 at 22:49

This question came from our site for peer programmer code reviews.

3  
see this : why-use-a-public-method-in-an-internal-class –  Kaan Feb 11 at 22:56
    
The short answer is that it doesn't matter. Public methods of an internal class are internal. To the compiler, the internal/public method distinction only matters for public classes. So just use whatever style you prefer. (There are probably hundreds of people on this board who'll want to argue with me over this.) –  Benjamin Hodgson Feb 12 at 7:45

2 Answers 2

As far as C# specification is concerned, there is no difference when you make a method internal or public so long as the type that holds it is internal. The only consideration might be that if you were to make the class public in the future, whichever methods you are likely to make public then, you could do that now. However, you may find differences of opinion even on this topic.

It comes to a matter of preference on your part (and your team) and I doubt that you may even get an agreement within your team if it's more than a few developers, let alone on a community as broad as this.

In addition, these preferences work well for any new code being written, but for any existing code, there is no benefit to justify the cost of changing the code (except for developer's own sanity). I have seen code written in both styles, even within the same project by two different developers.

As for the specification, pertinent parts of section 3.5.2 (p. 61) of C# 5.0 language specification states the following (and I believe it is the same in previous versions too):

The accessibility domain of a nested member M declared in a type T within a program P is defined as follows (noting that M itself may possibly be a type):

  • If the declared accessibility of M is public, the accessibility domain of M is the accessibility domain of T.
  • If the declared accessibility of M is internal, the accessibility domain of M is the intersection of the accessibility domain of T with the program text of P.

Since accessibility domain of T in your case is internal, so accessibility domain of M is the same regardless of it being internal or public.

share|improve this answer

just make sure that in your given language there is no what I'll call "side channel" through which consumers of your api could access a public member of an internal class, because if there is, and they find it and use it, that part of your code is "as good as" public api from then on. That means they scream if you change it and you get stuck supporting it.

In Java one example of a side channel is reflection. Devs can and have used it to gain access to members which the api author never intended they should know about.

share|improve this answer
    
There is not much one can do about Java reflection in the absence of a security manager, which in my experience is pretty rare in a Java application (and who uses Applets anymore?) –  Snowman Aug 20 at 2:06

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.