C SharpとJavaの比較
Javaではプリプロセッサがサポートされないため、コンパイル時の分岐は不可能となっている。
一方、C#ではプリプロセッサディレクティブを用いた条件付きコンパイル (条件コンパイル、英: conditional compilation) が実装されている。また、指定されたコンパイル定数が定義されている時のみ呼び出されるようConditional属性 (System.Diagnostics.ConditionalAttribute) をメソッドに指定することができる。この方法によって、DEBUG定数が定義されている時のみ評価される表明(アサート)機能 (System.Diagnostics.Debug.Assert()メソッド) が提供されている。
Java 1.4からは実行時に有効・無効を切り替えられるassert文が言語仕様として導入されている。
文字型: いずれの言語もUTF-16ベースの文字型を持つ。
ブーリアン型: いずれの言語もtrue/falseのいずれかを表すブーリアン型を持つ。
オブジェクト型: C#では組み込み型としてobject型を持つ。Javaのオブジェクト型java.lang.Objectは組み込み型ではない。
文字列型: C#では組み込み型としてstring型を持つ。Javaの文字列型java.lang.Stringは組み込み型ではない。
文字列はいずれの言語においても不変 (immutable) なオブジェクトとして扱われるが、特殊な構築方法として文字列リテラルを利用することができる。C#ではエスケープ文字を処理しないような逐語的文字列リテラル(verbatim文字列: ヒアドキュメントを参照)をサポートする。
C#言語自体にはプリミティブ型という用語は存在しないが、.NET Frameworkの共通言語ランタイム (CLR) では、System.Type.IsPrimitiveプロパティによって、型がCLRプリミティブ型であるかどうかを判定できる。.NET言語組み込みの値型は必ずしもCLRプリミティブ型ではないが、CLRプリミティブ型はすべて値型である。
いずれの言語もプリミティブ型(もしくは値型)と参照型との間で変換するためにボックス化 (boxing) とボックス化解除 (unboxing) が可能である。
NETいずれにも当てはまる)においてファイナライザの呼び出しは性能に大きな影響を与えるため、またファイナライザはプログラマがオブジェクトを破棄しなかった場合のフェイルセーフであるため、これは非常に有効である。ファイナライザをもつオブジェクトは通常余分な世代が与えられ、回収されるまでに長くかかる。
C#は、一部の言語設計者から危険であると指摘されるポインタを使用した演算が制限つきながら利用できる。C#はポインタを使用するコードブロックあるいはメソッドをunsafeキーワードで修飾することでこの懸念に対応している。これにより、このコードを利用する者はそれが他の部分に比べて危険であるということを知ることができる。また、このようなコードをコンパイルする際にはコンパイラに対して/unsafeスイッチを指定する必要がある。一般に、unsafeコードが使われるのはアンマネージなAPIやシステムコールとの相互運用が必要な時、あるいは性能の向上が必要な時のみである。
C/C++などで書かれたネイティブコード資産の再利用や、オペレーティングシステムあるいはハードウェアへのローレベルなアクセスを可能とするため、JavaおよびC#はともにネイティブ相互運用のための機能を提供している。
Java Native Interface (JNI) ではJavaコード内で非Javaコードをnativeメソッドとして呼び出すことができる。しかしながら、JNIは呼び出されるコードのインターフェイス(シグネチャ)に制限がある。このため、Javaと既存のネイティブコード資産との間に余分なレイヤーが必要になることがよくある。このレイヤーはJavaではない言語で書かれる必要があり、CやC++がよく用いられる。JNIを利用することで、逆にC/C++側からJavaのクラスライブラリにアクセスすることも可能である。
.NETのプラットフォーム呼び出し(Platform Invoke、P/Invoke)はC#からアンマネージコードの呼び出しを可能にする。プログラマはメタデータを通して、メソッドの引数や戻り値がどのように橋渡し(マーシャリング)されるかを完全に制御することができる。