C#と.NETのまとめ

C#とは何か

C#はマイクロソフトの.NET Frameworkプラットフォーム向けに開発された言語で、読み方は「シーシャープ」です。

マイクロソフトは古い開発技術の課題を一掃するため、統一され完全オブジェクト指向の統合開発基盤を必要とし、新たなコード実行環境と開発ツールチェーンの開発に着手しました。

20年以上の進化を経て、C#はWindows限定の言語から複数OSに対応するクロスプラットフォーム言語へと変化しました。

現在C#と.NETは完全なクロスプラットフォーム開発ソリューションを形成しており、Windows、macOS、Linux、Android向けアプリケーションの開発に利用可能。クラウドシステムの実行環境としても最も多く採用されています。

マイクロソフトの強力な支援によりC#のバージョンアップは非常に速いペースで進んでおり、2022年には7系がリリースされました。20年前に記述された古いコードとの互換性を保ちつつ、新バージョンはより簡潔で洗練された文法とコンパクトな構文が特徴で、2026年現在は第15版が最新となります。

C#バージョン開発年表(一部抜粋)

  • C# 1.0(2001年):正式リリース
  • C# 2.0(VS2005):ジェネリクス、イテレータ、匿名メソッド
  • C# 3.0(VS2008):拡張メソッド、ラムダ式、LINQ(言語統合クエリ)
  • C# 4.0(2010年):名前付き/オプション引数、dynamic動的型、TPL並列タスクライブラリ。マルチコアCPUの性能を最大限活用
  • C# 5.0:async/awaitによるネイティブ非同期タスク対応
  • C# 6.0:文字列補間、式本体メンバー、プロパティ簡略記法
  • C# 7.0~7.3:タプルによる複数戻り値、out引数簡略化、パターンマッチ、非同期Mainメソッド
  • C# 8.0/9.0/10.0:レコード(イミュータブル参照型)、トップレベルステートメント(Main不要)、デフォルトインターフェースメソッド、静的ローカル関数、非同期解放可能型、言語全体で利用可能なパターンマッチ
  • C#11 (.NET7):生文字列、ジェネリック数値演算、requiredプロパティ
  • C#12 (.NET8):プライマリコンストラクタ、コレクション簡略記法、インライン配列
  • C#13 (.NET9):部分プロパティ、拡張インデクサ、イテレータrefローカル変数
  • C#14 (.NET10):ジェネリックエイリアス、深いコレクションマッチ、SIMD構文糖衣

Windowsは依然としてC#の中心的な実行プラットフォームですが、.NETランタイムを活用することでLinuxなど各OS上でコードを直接実行でき、一度記述したコードを複数OSにデプロイ可能になっています。

.NET Frameworkについて

.NET Frameworkは2002年に初版が公開されました。

.NET Frameworkは旧世代開発技術の課題を解消するために登場し、主な強みは以下の通りです。

  1. マルチデバイス対応:サーバー、PC、PDA、スマートフォンなど多様なハードウェア上で動作;
  2. 業界標準へ準拠:XML、HTTP、SOAP、JSON、WSDLといった汎用通信プロトコルを標準でサポート;
  3. セキュリティサンドボックス:信頼できないソースのコードを隔離し、安全に実行させる仕組みを搭載。

.NET Frameworkの三大コアコンポーネント

  1. CLR共通言語ランタイム(実行環境) プログラムの実行ライフサイクル全体を制御:メモリ管理とガベージコレクション、コードの安全性検証、スレッドスケジューリング、例外処理を一括担う。
  2. 開発ツールセット 統合開発環境、複数の.NET言語コンパイラ(C#/VB.NET/F#など)、デバッガー、ASP.NET/WCFといったWebバックエンド技術を含む。
  3. BCL基本クラスライブラリ(FCLフレームワーククラスライブラリとも呼ばれる) 膨大な標準汎用クラスが事前実装されており、開発者は直接呼び出して利用可能。

従来のWindows開発と比較した.NETの進化ポイント

統一されたオブジェクト指向モデル

CLR、BCL、C#が深く連携し、統一されたOOPモデルを提供。デスクトップ、モバイル、Web、分散システムで同一の開発手法を活用でき、デバイスを跨いで文法・ロジックに一貫性が保たれます。

自動ガベージコレクション GC

CLRに標準搭載されたGCが不要になったオブジェクトのメモリを自動解放。開発者が手動でメモリ開放やメモリリーク調査を行う必要がなく、運用保守の負担が大幅に軽減されます。

多層的な相互運用性
  1. .NET言語間相互呼び出し:異なる.NET言語で作成したクラス同士で呼び出し・継承が可能で、プラットフォームが特定の言語に縛られない;
  2. P/Invokeプラットフォーム呼び出し ネイティブWin32 C言語DLLのAPIを直接実行;
  3. COM互換性:.NETコンポーネントと従来のCOMコンポーネントを双方向で呼び出せる。

デプロイが簡略化:レジストリへの依存がなく、最小構成ではファイルをコピーするだけでプログラムを実行可能;

サイドバイサイドアセンブリ:同一デバイスに複数バージョンのDLLを共存させられ、各アプリは自身のビルド時に使用したライブラリバージョンに紐付くため、DLLバージョン競合の問題が解消されます。

型安全性検証 CLR(共通言語ランタイム)が引数やデータ型を強制的に検証。異なる言語のコンポーネント同士が連携する際も型の安全性が保証され、不正なメモリアクセスを遮断します。

充実したBCL基本クラスライブラリ

汎用的な処理を実装した多数のユーティリティクラスが標準搭載

  • ファイル操作、文字列処理、暗号化・セキュリティといった基礎ツール;
  • リスト、ディクショナリ、ハッシュテーブルなどのコレクション;
  • マルチスレッド、同期・並行処理ユーティリティ;
  • XMLドキュメントの読み書き処理クラス
  • その他多数

汎用的な基盤ロジックが事前に実装済みのため、開発者は業務固有のロジックのみ記述すればよく、既存ライブラリを活用して重複実装を削減できます。

.NETプログラムの処理フロー図です。開発者が記述したコードは中間言語ILにコンパイルされ、ILはBCLが提供するライブラリを呼び出した後、CLRに渡され実行されます。

C#と.NETの関係性

.NET Framework:完全な開発・実行プラットフォームで、二つの中核コンポーネントから構成されます

  1. CLR(共通言語ランタイム):コードのメモリ管理、実行制御、安全性検証を担当
  2. BCL(基本クラスライブラリ):ファイル、ネットワーク、UI、並行処理など膨大な汎用ユーティリティコード群

C#プログラミング言語で、.NETプラットフォーム専用に設計され、CLR上で実行するコードを記述するために使用されます

C#以外にも.NETに対応するプログラミング言語が存在し、F#やVB.NETが代表的です。

.NET Frameworkの開発目的はクロスプラットフォーム・クロス言語対応です。クロスプラットフォームは複数OS上で動作すること、クロス言語は異なる言語で開発したコンポーネント同士が相互にアクセス可能なことを指します。

共通中間言語(CIL)へのコンパイル

.NET対応言語のコンパイラはソースコードファイルを読み込み、アセンブリ(assembly)という出力ファイルを生成します

アセンブリには二種類が存在:実行ファイル(exe)または動的リンクライブラリ(DLL)です

アセンブリ内部のコードはCPUが直接解釈するネイティブ機械語ではなく、共通中間言語(Common Intermediate Language、CIL)という中間コードで記述されています。

一つのアセンブリには主に以下の要素が格納されています:

  1. プログラムのCIL命令コード
  2. プログラム内の全型に関するメタデータ
  3. 外部の他アセンブリとの参照関係を記録したメタデータ

中間言語の略称は.NETの発展に伴って変更されており、資料によって表記が分かれます。中間言語(IL)マイクロソフト中間言語(MSIL)はいずれもCILを指す用語です。

ネイティブコードへ変換・実行

CILは事前にネイティブ機械語に変換されず、プログラム実行時にCLRが以下3段階の処理を実施します:

  1. アセンブリのセキュリティ情報検証
  2. 実行用メモリの確保
  3. JITコンパイラに渡し、分割してネイティブコードへ変換
JITオンデマンドコンパイル機構

実際に実行されるコードブロックのみコンパイルし、変換後はキャッシュして再利用。呼び出されないコードはコンパイルされず、同一コードブロックは一度だけ変換処理が走ります。

アセンブリ (CIL + 型情報) → CLR (JITコンパイラ) → ネイティブコード → OSシステムサービス

CLRの管理下で実行される処理

CILをネイティブコードに変換後、CLRが自動的に以下を制御:ガベージメモリ回収、配列境界チェック、引数型検証、例外ハンドリング。

マネージドコードとアンマネージドコード
  • マネージドコード:.NET言語で記述したコード。CLRによる実行管理下で動作
  • アンマネージドコード:CLRによる管理を受けないコード。C/C++製のWin32 DLLなどが該当

現在マイクロソフトはAOTコンパイルに対応しており、C#コードを事前にネイティブ機械語に変換可能。C++のように.NETランタイムを事前インストールしなくてもEXEファイルを直接実行できます。

NGenツール

オフラインでアセンブリを事前コンパイルしネイティブイメージを作成。実行時にJIT変換工程を省略でき、アプリ起動速度が向上します。

.NET Core AOTは次世代の事前コンパイル手法で、ランタイムに依存しない単体のネイティブ実行ファイルを出力できます。

Assembly (型情報, CIL)
        ↓
JIT コンパイラ
        ↓
ネイティブコード
        ↓
OS システムサービス

元のソースコードがどのプログラミング言語で記述されていても、同一のコンパイル・実行フローが適用されます。

各言語に専用のコンパイラが用意されており、VB.NETにはVB用コンパイラ、C#にはC#用コンパイラが存在。それぞれのコンパイラがソースをCILに変換し、CILはJITを経てネイティブコードになりCPUで実行されます。これが.NET製ソフトを動かすために.NETランタイムのインストールが必要な理由で、JavaがJREを必要とする仕組みと同じです。

flowchart TD
    subgraph コンパイル時
        A[C# ソース] --> B[C# コンパイラ]
        B --> C[アセンブリ CIL]
        D[VB ソース] --> E[VB コンパイラ]
        E --> C
        F[その他.NETソース] --> G[対応言語コンパイラ]
        G --> C
    end

    subgraph 実行時
        C --> H[JIT コンパイラ]
        H --> I[ネイティブコード]
        I --> J[OSシステムサービス]
    end

上図は各言語のコンパイルから実行までの一連の流れを示した図です。

共通言語ランタイム(CLR)

.NET Frameworkの中核コンポーネントがCLRで、OSの上位層に位置しプログラムの実行を統括管理します。

  • 自動ガベージコレクション(GC)
  • BCLを活用した安全性検証・認証処理
  • Webサービス、データサービスなど多様なプログラミング機能を提供
flowchart TD
    subgraph アンマネージドコード
        A[非.NETプログラム] --> OS[オペレーティングシステム]
    end

    subgraph マネージドコード
        B[アセンブリ] --> CLR[共通言語ランタイム]
        C[アセンブリ] --> CLR
        D[アセンブリ] --> CLR

        subgraph CLR[共通言語ランタイム]
            M[メモリ管理] --- E[例外処理]
            G[ガベージコレクション] --- R[リフレクション機能]
            J[JITコンパイラ] --- L[クラスローダー]
            S[セキュリティ機能]
        end

        CLR --> OS
    end

共通言語基盤(CLI)

各プログラミング言語には整数、浮動小数点数、文字などを表現する標準基礎型が実装されています。

共通言語基盤(CLI)は一連の規格群で、.NET Frameworkの全コンポーネントを統一され互換性のある体系にまとめ上げます。

例えば整数型が使用するビット幅は全ての対応言語で統一されています。

flowchart TD
    subgraph CLI[共通言語基盤]
        CLR[共通言語ランタイム] --- CLS[共通言語仕様]
        BCL[基本クラスライブラリ] --- MDS[メタデータ定義・意味規則]
        CTS[共通型システム] --- CIL[共通中間言語]
    end

開発者がCLIの全規格を深く理解する必要はありませんが、CTS共通型システムCLS共通言語仕様の知識は必須です。

CTS 共通型システム

  • 規格化された基礎データ型を標準搭載、各型の仕様は固定;
  • 各.NET言語固有の型は全てこの標準型のサブセットにマッピングされる;
  • 全ての型はルートクラス object を継承;
  • 統一規格によりシステム標準型とユーザー定義型が、どの.NET言語間でも相互に利用可能。

CLS 共通言語仕様

.NETに対応する言語が順守すべき統一ルールを定義。データ型、クラスのコンストラクタ、引数受け渡しといった言語間連携の制約事項をカバーしています。

.NETと.NET Frameworkの違い

.NETはマイクロソフトが現在推進するクロスプラットフォーム開発プラットフォーム、.NET Frameworkは初期版のWindows専用ランタイム&ライブラリです。新機能開発は.NET側に集中され、.NET Frameworkは保守フェーズに入り、セキュリティ更新のみ提供されています。

.NETはクロスプラットフォーム対応で、現在マイクロソフトの主力開発基盤となっています。本記事以降の解説も.NETを中心に記載します。

特徴.NET.NET Framework
対応プラットフォームクロスプラットフォーム(Windows、Linux、macOS、コンテナ、MAUIによるモバイル)Windows限定
開発状況継続的バージョンアップ(.NET 5~.NET10、毎年リリース、LTS長期サポート)保守モード(4.8が最終版、セキュリティパッチのみ)
パフォーマンス起動高速化、処理スループット向上、GC処理の最適化古いアーキテクチャでWindows APIに依存、性能面で劣る
活用シナリオ新規開発:Web API、マイクロサービス、クラウドネイティブ、クロスプラットフォームデスクトップ/モバイルレガシープロジェクト:Web Forms、WCF、Windows Workflowなど
デプロイ方法Docker・コンテナ、クラウド環境に完全対応コンテナ非対応、Windows Serverに依存
対応言語C#、F#、VB.NET(全OS対応)C#、VB.NET(Windowsのみ)

.NETと.NET Frameworkの差異は大きくありません。双方ともC#、F#、VB.NETなどの言語を利用し、中核文法は共通です。大半のケースで同じC#コードを.NET Frameworkと.NET(Core/5/6/7/8…)双方でコンパイル・実行可能です。

主な違いは文法ではなく、利用可能なクラスライブラリにあります。

.NET Frameworkに実装されていたWCFWeb FormsWindows Workflowは最新の.NETで削除、または代替技術に置き換えられています。

最新の.NETにはSpan<T>ValueTaskRecordsといった新しいAPIが追加されており、旧.NET Frameworkでは使用できません。

.NET FrameworkがWindows専用であるのに対し、.NETはクロスプラットフォームのため、Windows固有のライブラリの一部が削除されています。例えばSystem.DrawingはWindows上で利用可能ですが、クロスプラットフォーム版.NETではWindows限定APIとして分類されます。.NETで画像描画処理を実装する場合、System.Drawingの代わりにGoogle製SkiaSharpといったサードパーティライブラリを使用する必要があります。

注意点:上記はフレームワーク層の差異で、C#といった言語レベルではほとんど違いがない。記述するC#の文法は両環境で同一です。真の差異:クラスライブラリと実行環境、つまり利用できるAPIに差が存在するという点です。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です