Почему не работает шаблон Bloch Builder в С#

Рассмотрим стенографическую копию шаблона Bloch Builder (с изменениями, внесенными для синтаксиса С#):

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;
  }
}

Если вы попытаетесь запустить это, компилятор С# будет жаловаться на то, что у него нет разрешения на доступ к приватным свойствам Builder. Однако в Java вы можете это сделать. Какое правило отличается от С#, что препятствует доступу к закрытым свойствам вложенных классов?

(Я понимаю, что люди предоставили альтернативы здесь и это здорово. Меня интересует, почему вы не можете использовать шаблон Java без изменений).

Ответ 1

В Java частные члены внутренних/вложенных классов доступны для содержащего класса. В С# это не так.

Ответ 2

Я не понимаю, почему это должно быть разрешено компилировать. Вы пытаетесь получить доступ к закрытым полям класса извне этого класса. Однако Java содержит специальное правило для вложенных классов, которое обеспечивает доступ из внешнего класса.

Ответ 3

Уровни доступности С# заключаются в следующем:

  • public: доступ не ограничен.
  • protected: доступ ограничен содержащим классом или типами, производными от содержащего класса.
  • internal: доступ ограничен текущей сборкой.
  • protected internal: доступ ограничен текущей сборкой или типами, производными от содержащего класса.
  • закрытый. Доступ ограничен типом содержимого.

В С# нет особого случая для вложенных классов, в результате вы не можете получить доступ к частному члену извне этого класса или любого класса, полученного из этого класса.

Дополнительную информацию вы можете найти в следующей статье MSDN: Уровни доступности (С#)

Ответ 4

Gilad Bracha утверждает, что позволяет внешним классам доступ к частным лицам вложенных классов прерывает "правило подчинения систем типов для языков OO".