「名前空間」と「モジュール」の両方の用語をオーバーロードすることを選択しているようです。定義に適合しない場合に「間接的」と見なされるのは当然のことです。
C#を含む名前空間をサポートするほとんどの言語では、名前空間はモジュールではありません。名前空間は名前をスコープする方法です。モジュールはスコープ動作の方法です。
一般に、.Netランタイムはモジュールの概念をサポートしますが(暗黙的に使用しているものとは少し異なる定義で)、それはめったに使用されません。SharpDevelopでビルドされたプロジェクトで使用されるのを見ただけで、主に、さまざまな言語でビルドされたモジュールから単一のDLLをビルドできました。代わりに、動的にリンクされたライブラリを使用してライブラリを構築します。
C#では、名前空間は、同じバイナリ内にある限り、「間接層」なしで解決されます。必要な間接処理は、コンパイラやリンカの責任であり、あまり考慮する必要はありません。複数の依存関係を持つプロジェクトの構築を開始したら、外部ライブラリを参照します。プロジェクトが外部ライブラリ(DLL)への参照を作成すると、コンパイラがそれを見つけます。
Schemeでは、外部ライブラリをロードする必要がある場合、(#%require (lib "mylib.ss"))
最初に何かをするか、外部関数インターフェイスを直接使用する必要があります。外部バイナリを使用している場合、外部バイナリを解決するために同じ量の作業が必要です。ほとんどの場合、使用頻度の高いライブラリを使用していて、それを抽象化するSchemeベースのシムがありますが、サードパーティライブラリとの独自の統合を作成する必要がある場合は、基本的に「ロードする」ための作業が必要になります。 " 図書館。
Rubyでは、モジュール、名前空間、およびファイル名は、実際には、想定しているように接続されていません。LOAD_PATHは少し複雑になり、モジュール宣言はどこにでも置くことができます。Pythonはおそらく、Schemeで見ていると思う方法に近いですが、Cのサードパーティライブラリがまだ(小さな)しわを追加している点が異なります。
さらに、Ruby、Python、Lispのような動的に型付けされた言語には、通常、静的に型付けされた言語と同じ「契約」へのアプローチがありません。動的に型付けされた言語では、通常、コードが特定のメソッドに応答する一種の「紳士協定」のみを確立します。クラスが同じ言語を話しているように見える場合、すべてが適切です。静的型付け言語には、コンパイル時にこれらのルールを適用するための追加のメカニズムがあります。C#では、そのようなコントラクトを使用することで、これらのインターフェイスの順守について少なくとも適度に有用な保証を提供できます。これにより、すべてが同じコントラクトに対してコンパイルされるため、プラグインと置換をある程度の共通性の保証とともにバンドルできます。RubyまたはSchemeでは、実行時に機能するテストを作成して、これらの合意を検証します。
メソッドの呼び出しには二重ディスパッチが必要ないため、これらのコンパイル時間の保証から測定可能なパフォーマンス上の利点があります。Lisp、Ruby、JavaScript、または他の場所でこれらの利点を得るには、今でも特殊なVMでジャストインタイムの静的コンパイルクラスのわずかにエキゾチックなメカニズムであるものが必要です。
C#エコシステムがまだ比較的未熟なサポートを持っていることの1つは、これらのバイナリ依存関係の管理です。Javaは数年前からMavenを使用して必要な依存関係をすべて確実に処理していましたが、C#にはまだ事前に適切な場所にファイルを戦略的に配置するというかなり基本的なMAKEのようなアプローチがあります。