Java と C# の アクセシビリティの違い

アクセス修飾子(public/private/protected/internal/protected internal /指定無し) の違いの話しでは無いです。

private や 指定無し等で外から*1アクセス出来ないクラスがあった時に、そのクラスを外部に公開出来るかどうかの話しです。
こういうのは、コード例を見ると手っ取り早いですね。

Main.java

class Hoge {
  public final PrivateClass privateClass = new PrivateClass();
  public final PublicClass publicClass = new PublicClass();
  private static class PrivateClass{}
  public static class PublicClass{}
}
public class Main {
  public static void main(String... args) {
    Hoge h = new Hoge();
    Hoge.PublicClass publicClass = h.publicClass;
    // Hoge.PrivateClass privateClass = h.privateClass; コンパイルエラー
    Object privateClass = h.privateClass;
    System.out.println(publicClass); // Hoge$PublicClass@...
    System.out.println(privateClass); // Hoge$PrivateClass@...
  }
}

private なクラスを public なフィールドを通して外に公開しています。
もちろん、外では private なクラスは宣言出来ないので Object で受ける必要がありますが。

Program.cs

using System;
class Hoge {
  public readonly PublicClass publicClass = new PublicClass();
  // コンパイルエラー になるので、private にしている
  // public readonly PrivateClass privateClass = new PrivateClass();
  private readonly PrivateClass privateClass = new PrivateClass();
  public class PublicClass { }
  private class PrivateClass { }
}
class Program {
  static void Main(string[] args) {
    var h = new Hoge();
    var publicClass = h.publicClass;
    // var privateClass = h.privateClass; private なのでアクセス出来ない
    Console.WriteLine(publicClass); // Hoge+PublicClass
  }
}

C# の場合は、次のようなコンパイルエラーが出て Java で書いたような事が出来ません。

アクセシビリティに一貫性がありません。フィールドの型 'Hoge.PrivateClass' のアクセシビリティはフィールド 'Hoge.privateClass' よりも低く設定されています。

C# でダメなのは知っていたんですが、Java では一応書けるんですね~、知らなかった。。

*1:別クラス/別アセンブリ/別パッケージ等々