◆ 引数や返り値の型のアクセス可能範囲とメソッドのアクセス可能範囲をあわせないといけないです

c# ではアクセス可能範囲を表す public や private が PHP より複雑です

アクセシビリティ

JavaScript だと 基本すべてが public でどうしても隠したいのがあればクロージャで見えなくするくらいなので こういうのは便利ですがめんどうにも感じます

MSDNリファレンス だとこう書かれています

publicアクセスの制限はありません。
protectedアクセスは、コンテナー クラス、またはコンテナー クラスから派生した型に制限されます。
internalアクセスは現在のアセンブリに制限されます。
protected internal現在のアセンブリ、またはコンテナー クラスから派生した型に制限されるアクセス
privateアクセスはコンテナー型に制限されます。

コンテナーと書かれているのは class 以外にも enum や struct などでも使うキーワードだからのようです
public と private 以外に protected, internal, protected internal があります

わかりづらいです

public:どこからでもおっけい
private:同じクラス内だけ
protected:同じクラスと そのクラスを継承した子クラスからだけ

ここまでは PHP と一緒なのでわかりますが internal というのが存在します

「アクセスは現在のアセンブリに制限されます」

なにいってんの??

調べてると アセンブリをプロジェクトと言い換えてるところがありました
アセンブリを exe ファイルのことと考えると 1 プロジェクトでは 1 つの実行ファイルが作られるわけですし なんとなくわかるような気がします

ソリューションとプロジェクト

Visual Studio だとソリューションというのとプロジェクトというのがあります
開くときに拡張子が sln だったり proj だったりするやつです

1 つだけメイン関数があって 1 つの実行ファイルを作るものがプロジェクトと呼ばれます
ソフトによっては アップデーターとか設定ファイル編集ツールやセーブデータコンバートツールとか複数の実行ファイルがあるものもありますよね
そういうのはそれぞれがプロジェクトで複数のプロジェクトがあるということになります
そして 1 つのソフトに関わるプロジェクトをまとめたものがソリューションです

最近までソリューション?プロジェクト?なにそれ
だったんですが こういう使い分けと知って納得しました

internal

話を戻して internal です
アセンブリが exe ファイル(プロジェクト) と考えると 別プロジェクトからアクセス禁止したい時に使えます

protected internal は同じプロジェクトか 継承されたクラスからアクセスできることになります

protected internal が存在するということは 別プロジェクトのクラスを継承できるようです
同一プロジェクト内しか継承できなければ internal に含まれるので protected 部分が不要になります

ですが 別々に動いている exe ファイルなのに継承したり内部のクラス単位でアクセスできるってできるんでしょうか?
Windows ソフトは全然詳しくないのでわからないですが できるイメージが掴めません

a.exe が b.exe のクラスを継承して b.exe の方のプロパティにアクセスできるってもうどうなってるの それ


JavaScript 風に考えて a.html が b.html を iframe で開いて 親の a.html の JavaScript が子の b.html の中の JavaScript や DOM を操作できるみたいなものなんでしょうか……

アクセシビリティに一貫性がありません

今回は internal や protected internal の仕組みがどうこう言いたいわけじゃないので置いておきます
とりあえず

public > protected internal > internal ≒ protected > private

くらいにアクセス許可レベルのゆるさがわかればいいです
internal と protected はプロジェクト単位か継承したクラス単位かで別の考え方なのでどっちがゆるいとはいえないので同じくらいになってます

c# でよく目にする

アクセシビリティに一貫性がありません

というエラー
これが慣れない人だとどうすればいいのか なぜ起きるのかわからなくて困ります
これの対処方法です

このコードではそのエラーが出ます
class test1
{
}

public class test2
{
public void func(test1 data)
{
}
}

test1 は public などのアクセス可能レベルを省略しています
クラスの場合は省略すると internal になります

func メソッドの引数に問題があると言われます

原因は test1 が internal だからです
test2 は public で func メソッドも public です
つまり func メソッドは別プロジェクトであろうとどこからでも呼び出せます

しかし 呼び出す時の引数 test1 は internal で同じプロジェクトでしかアクセスできません
実質同じプロジェクトからしか呼び出せないということです

それなら public と書いたけど test1 の internal と同じ範囲でしか使えないだけで public と書くこと自体に問題ないのでは? と思いますが それもダメになってるようです
この場合は func メソッドを internal にして
class test1
{
}

public class test2
{
internal void func(test1 data)
{
}
}

こうすればおっけいです

PHP のクセでつい public を書いてしまいますが クラスに public とか書かなかったら internal になりますし プロジェクト複数作る気がないなら internal と書くようにしたほうがいいかもしれないです