11

Consider a verbatim copy of Bloch's Builder pattern (with changes made for C#'s syntax):

public class NutritionFacts
{
  public int ServingSize { get; private set; }
  public int Servings { get; private set; }
  public int Calories { get; private set; }
  ...
  public class Builder
  {
    private int ServingSize { get; set; }
    private int Servings { get; set; }
    private int Calories { get; set; }

    public Builder(int servingSize, int servings)
    {
      ServingSize = servingSize;
      Servings = servings;
    }

    public Builder Calories(int calories)
    { Calories = calories; return this; }

    public NutritionFacts Build()
    {
      return new NutritionFacts(this);
    }
  }

  private NuitritionFacts(Builder builder)
  {
    ServingSize = builder.ServingSize;
    Servings = builder.Servings;
    Calories = builder.Calories;
  }
}

If you try to run this, the C# compiler will complain that it doesn't have permission to access the private properties of Builder. However, in Java, you can do this. What rule is different in C# that prevents you from accessing private properties of nested classes?

(I realize that people have given alternatives here and that's great. What I'm interested is why you can't use the Java pattern without modification).

Community
  • 1
  • 1
cdmckay
  • 31,832
  • 25
  • 83
  • 114
  • Hi I asked this exact question.Got some pretty good answers. Here we go [http://stackoverflow.com/questions/512651/how-is-javas-notion-of-static-different-from-cs](http://stackoverflow.com/questions/512651/how-is-javas-notion-of-static-different-from-cs) – uriDium Jul 03 '09 at 18:35

4 Answers4

19

In Java private members of inner/nested classes are accessible to the containing class. In C# they aren't.

Laurence Gonsalves
  • 137,896
  • 35
  • 246
  • 299
  • 1
    The compiler enables this by generating synthetic accessors with appropriate permissions. Sorry to revive an old thread... – Jonathan Mar 22 '11 at 19:33
  • @Jonathan: Yes, that's true. This has to do with the fact that the JVM doesn't really know about nested classes, and so the synthetic methods are necessary to get the desired behavior. My impression was that the question was about the Java language, not the JVM. – Laurence Gonsalves Mar 23 '11 at 00:31
  • 1
    Exactly. I was just trying to provide more information, in case anyone stumbled across this in the future. – Jonathan Mar 23 '11 at 18:50
  • @Jonathan I am from the future! Thank you! – AncientSwordRage Mar 14 '13 at 23:59
3

I don't see why that should be allowed to compile. You are trying to access the private fields of a class from outside that class. Java, however, contains a special rule for nested classes that allows access from the outer class.

JoshJordan
  • 12,676
  • 10
  • 53
  • 63
3

The accessibility levels in C# are as follows:

  • public: Access is not restricted.
  • protected: Access is limited to the containing class or types derived from the containing class.
  • internal: Access is limited to the current assembly.
  • protected internal: Access is limited to the current assembly or types derived from the containing class.
  • private: Access is limited to the containing type.

There is no special case in C# for nested classes, as a result you cannot access a private member from outside that class or any class deriving from that class.

You can find more information in the follow MSDN article: Accessibility Levels (C#)

Richard McGuire
  • 10,780
  • 8
  • 31
  • 34
0

Gilad Bracha argues that allowing outer classes access to the privates of nested classes breaks "the subsumption rule of type systems for OO languages."

Tom Hawtin - tackline
  • 145,806
  • 30
  • 211
  • 305