7

For example:

internal class C
{
    public void M()
    {
        Console.WriteLine("foo");
    }
}

To me, that reads "a method that can be accessed by anyone, regardless of assembly living inside a class that can only be accessed from code in the same assembly".

My experience with the compiler tells me that if I do something like that and do not get a warning, there is probably a valid reason to have it.

So, I suppose either

  1. Something is lacking in my understanding of protection levels.
  2. There could be a warning but there isn't one.

(if 2, this is not an attempt to complain about it - I just want to understand)

Aaron Anodide
  • 16,906
  • 15
  • 62
  • 121
  • Maybe the compiler knows that `C` and `M` aren't real code... ? algo: one char variable => Good Luck I quite... :) – gdoron Apr 30 '12 at 21:07
  • Any why is `private class C { }` not allowed but `class C { }` is allowed? Sometimes `C#` is rigid for the sake of being rigid. – John Alexiou Apr 30 '12 at 21:18
  • 2
    @ja72: C# is not rigid for the sake of being rigid; it is rigid for the sake of providing value to developers who prefer their tool to tell them when they have an error. `private class C{}` is perfectly legal *inside a type*; `class C{}` means the same thing as `private class C{}` *inside a type*. `private class C{}` is not allowed *outside a type* because `private` means "private to this type", which is obviously nonsensical outside a type! In C#, `internal class C{}` can be used outside a type, and `class C{}` means the same thing outside a type. – Eric Lippert Apr 30 '12 at 21:48
  • @EricLippert: Well for me `private` means private within a namespace also, as it is implied. – John Alexiou May 01 '12 at 00:14
  • 2
    @ja72, there is no such thing as “private withing a namespace” in C#. Namespaces are there to organize code, not to decide who has access to what. – svick May 01 '12 at 01:26
  • 4
    @ja72: svick is correct; namespaces are not *access control mechanisms*. Namespaces are just a convenient way to organize code; at the CLR level, there is no such thing as a namespace. "namespace N { class C {}} is just a fancy way of writing "class N.C {}". That's not legal C#, but that's how the CLR sees it. – Eric Lippert May 01 '12 at 05:33

4 Answers4

10

To me, that reads "a method that can be accessed by anyone, regardless of assembly living inside a class that can only be accessed from code in the same assembly".

To me that means "the accessibility domain of C is restricted to this assembly; the accessibility domain of M is the unrestricted subset of the accessibility domain of its container, C".

"public" means that to me because that's what the specification says it means. I encourage you to read the portion of the specification which covers accessibility domains if you have questions or concerns about this.

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • my question was trying to get at "why would you do this" as I can plainly see it's possible - are you saying the spec would make me understand the motivations behind it? At any rate, I continue to have aspirations of reading it front-to-back and appreciate the encouragement. – Aaron Anodide May 01 '12 at 03:26
  • This is a much, much, *much* nicer description of how `public` works than all the other answers which kind of try and fail wrapping the behaviour into words. – Joey May 03 '12 at 07:27
5

The internal keyword is going to limit access to M() to only calls made within the assembly in which C resides.

public just means anyone can access the member. public doesn't know or care anything about restrictions placed on it higher up in the class hierarchy, nor should it.

It's "by design," in other words. When you put public on a method, the compiler assumes you already know that, if you impose further restrictions on the class itself, then you must know what you are doing.

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
  • He knows that, he's asking why doesn't a public inside of an internal give him an error\warning. – gdoron Apr 30 '12 at 21:08
  • 2
    Because `public` just means anyone can access the member. `public` doesn't know or care anything about restrictions placed on it higher up in the class hierarchy, nor should it. – Robert Harvey Apr 30 '12 at 21:10
5

See this SO Question for a detailed answer on how it functions.

In my experience, I like to mark internal members public in anticipation of a future time when I want to change the scope of the class to public. This way I can do that and all the previously marked internal methods are automatically public.

Community
  • 1
  • 1
Steve Danner
  • 21,818
  • 7
  • 41
  • 51
  • 3
    Yes, exactly. Why should you have to change every access modifier in your class when you can change *one* and accomplish the same thing. – Robert Harvey Apr 30 '12 at 21:12
  • 1
    i totally get it now from these answers... it's this crossroads where practical meets logical that i get confused most often - YEARS i've been scratching my head at this and simply never thought to ask here assuming I was just unaware of some finer point – Aaron Anodide Apr 30 '12 at 21:34
2

The scope of the class is internal, so while it doesn't seem to make sense to have public property, in that only those classes also in the name space will be able to see the class to see the property. If at some point you decided to make the class public it would be a massive PIA to go through every member and change it's scope.

Tony Hopkinson
  • 20,172
  • 3
  • 31
  • 39