本文へスキップ
G# とは — Go・Kotlin・Swift の書き味を .NET に持ち込むモダン言語のアイキャッチ画像
Architecture

G# とは — Go・Kotlin・Swift の書き味を .NET に持ち込むモダン言語

公開: 更新: 約7分で読めます

「モダンで簡潔な構文が欲しい。でも .NET のランタイムや資産は手放したくない」——その両方を狙う新しい言語 G#(ジー・シャープ) が登場しました。作者は David Obando 氏で、2026 年 7 月に 0.3 リリースを発表。Go・Kotlin・Swift の書き味を取り入れつつ、マネージドアセンブリへ直接コンパイルして .NET と完全に相互運用するのが特徴です。Microsoft の著名エンジニア David Fowler 氏も「新しい .NET 言語 G#」として紹介し、注目を集めています。本記事では、G# が何を狙い、どんな構文で、.NET とどうつながるのかを、コードと図で整理します。

G# とは何か

G# は、.NET のマネージドアセンブリへ直接コンパイルするプログラミング言語です。Go のパッケージ設計、Kotlin・Swift の null 安全といったモダンな言語設計を取り入れつつ、CLR ランタイム・BCL・NuGet・MSBuild・Portable PDB・C# 相互運用といった.NET の資産をそのまま使えます。作者は狙いをこう述べています。「C# は優秀だが、大きく、数十年の歴史を背負っている。G# は言語表面を小さく予測可能に保つ、という別の制約から始める」。

G# の立ち位置の図。左『モダンな書き味』(Go のパッケージ/簡潔な構文、Kotlin・Swift の null 安全、data class・パターン switch、明示的な数値型)+右『.NET の資産(そのまま)』(CLR ランタイム/BCL・NuGet、MSBuild、Portable PDB、C# 相互運用)。マネージドアセンブリへ直接コンパイルして両立する。
G# は「モダンな書き味」と「.NET の資産」の両取りを狙う。現在は v0.3(プレ 1.0)。

モダンで簡潔な構文

まずは定番の挨拶から。package と import、func 宣言、そして ${...} の文字列補間が並びます。Go や Kotlin を触ったことがあれば、ほぼ説明なしで読めるはずです。

package Hello
import System

func greet(name string) string {
    return "Hello, ${name}!"
}

Console.WriteLine(greet("world"))

data class は、構造的等価・with によるコピー・分解代入を自動生成します。C# のレコードに近い発想を、より短い記述で得られます。

data class Person(Name string, Age int32)

let alice = Person("Alice", 30)
let older = alice with { Age = 31 }
let (n, a) = older

Console.WriteLine(alice == Person("Alice", 30))  // True

null の扱いは型システムに組み込まれています。null ではなく nil を使い、素の T は nil を持てず、T? だけが nil を許容します。取り出しは if let で安全に行えます。

func Greet(name string?) {
    if let n = name {
        Console.WriteLine("hi ${n}")
    } else {
        Console.WriteLine("hi stranger")
    }
}

Greet("Ada")
Greet(nil)
G# の主な言語機能の図。data class(構造的等価・with コピー・分解を自動生成)、null 安全(T は nil 不可・T? のみ nil 可、if let)、構造化並行(scope が子タスクの join を保証、async/await)、明示的な数値型(int8/uint16/int32/uint64/float64)。
C# より小さく予測可能な言語表面を目指す、G# の代表的な機能。

構造化並行と、明示的な数値型

非同期は async/await が Task・Task[T] の上で動きます(G# のジェネリクスは 角括弧 [] で書きます)。特徴的なのが scope { ... } ブロックで、内部で開始した子タスクの完了(join)を自動で待ち合わせる構造化並行を強制します。非同期ストリームは async sequence[T] で表せます。

async func compute(n int32) int32 {
    await Task.Delay(5)
    return n * 2
}

async func runAll() {
    let a = await compute(3)
    let b = await compute(4)
    Console.WriteLine("a = ${a}, b = ${b}")
}

scope {
    runAll().Wait()
}

数値型は 幅を名前に持つプリミティブ(int8 / uint16 / int32 / uint64 / float32 / float64)で、値のサイズがソース上で明示されます。暗黙の曖昧さが減り、意図が読み取りやすくなります。

.NET との相互運用

G# の実用性を支えるのが、あらゆる .NET 型をそのまま呼べる相互運用です。BCL、NuGet パッケージ、既存のユーザーコードを呼び出せ、LINQ・プロパティ・インデクサ・IEnumerable[T] に対する for-in ループも自然に書けます。コンストラクタ・オーバーロード・イベント・デリゲート・ref/out/in・演算子・ジェネリクス・構造体マーシャリングまで対応します。ネイティブ相互運用(P/Invoke)も属性で書けます。

import System.Runtime.InteropServices

@DllImport("libc", EntryPoint: "strlen", CharSet: CharSet.Ansi)
func StrLen(text string) nint;

Console.WriteLine(StrLen("Hello, world!"))

xUnit のような既存のテスト資産もそのまま活用できます。下は G# で書いたテストで、@Fact / @Theory / @InlineData といった .NET のテスト属性を用いています。「新しい言語だが、.NET のエコシステムの中にいる」ことが伝わる例です。

G# で書いた xUnit スタイルのテストコード。@Fact な Greet_Returns_Hello_With_Name と、@Theory+@InlineData(Alice/Bob) な Greet_Formats_Each_Name。func 宣言と Assert.Equal(greeter.Greet(...)) を使っている。
G# で書いた xUnit スタイルのテスト。@Fact/@Theory/@InlineData など .NET の資産をそのまま使える(出典: David Obando 氏の記事)。

ツールと、始め方

ツール群も一通り揃っています。CLI コンパイラ gsc(マネージド PE と Portable PDB を出力)、REPL/スクリプトランナー gsi、C#→G# 変換ツール cs2gs(変換→コンパイル→IL 検証→テスト等価性まで通す)、VS Code 拡張、そして LSP 実装の言語サーバーです。実際に手を動かす手順は、次のチュートリアルで示します。

0.3 では、throw 式・値を返す ++/--・範囲・コレクション初期化子といった式の追加、*T・stackalloc・fixed のunsafe ポインタ、C# 互換の数値変換、cs2gs 移行ツールと Roslyn ソースジェネレーター対応、増分バインディング等の性能改善が入りました。

はじめての G# — かんたんチュートリアル

実際に動かすのが理解の近道です。必要なのは .NET SDK だけ。テンプレートから作って走らせる、次の 3 ステップで最初の G# プログラムが動きます。

3 ステップで始める G# のフロー図。①テンプレート導入 dotnet new install Gsharp.Templates →②プロジェクト作成 dotnet new gsharp-console -n HelloG →③ビルド&実行 cd HelloG && dotnet build && dotnet run。コンソールに Hello, world! が出れば成功。
3 ステップで最初の G# を動かす流れ。REPL の gsi や C#→G# の cs2gs も併用できる。

① テンプレートを入れて、プロジェクトを作る。

dotnet new install Gsharp.Templates
dotnet new gsharp-console -n HelloG
cd HelloG

② 少しだけコードを書く。 生成された Program.gs を、data class と with コピー・構造的等価を使った例に書き換えてみます。

package HelloG
import System

data class Person(Name string, Age int32)

func describe(p Person) string {
    return "${p.Name} (${p.Age})"
}

let alice = Person("Alice", 30)
let older = alice with { Age = 31 }

Console.WriteLine(describe(alice))
Console.WriteLine(describe(older))
Console.WriteLine(alice == Person("Alice", 30))

③ ビルドして実行する。

dotnet build && dotnet run

次のように出力されれば成功です。with による部分コピーと、構造的等価がそのまま効いていることが確認できます。

Alice (30)
Alice (31)
True

もっと手軽に試すなら、REPL の gsi に式を打ち込むだけでも動きます。既存の C# を寄せていきたいときは cs2gs が変換を助けてくれます。

どう捉えるか — .NET 開発者の視点

G# が響くのは、モダンで小さな言語表面を好みつつ、CLR の相互運用も本気で欲しい開発者や、C# から始めずに .NET を学ぶ・教える場面、そして Go のパッケージ設計や Kotlin/Swift の null 安全を CLR 上で味わいたい人です。C# の置き換えを迫るものではなく、「.NET 上の言語選択肢が増える」と捉えるのが実態に近いでしょう。

一方で、G# は プレ 1.0 の段階です。0.3 は実装マイルストーンであり、長期の互換保証ではありません。CLR 相互運用の一部は emit のみ(呼び出し側の生成に限定)で、cs2gs の移行カバレッジも拡大中とされています。本番採用より、まずは小さな検証や学習から触れ、更新に追随できる範囲で試すのが安全です。

開発者の声(X より)

G# を広く知らしめたきっかけの一つが、Microsoft の Distinguished Engineer で ASP.NET Core などを手がける David Fowler 氏の投稿です。短く「新しい .NET 言語 G#」と添えられただけですが、.NET コミュニティの中心人物が取り上げたことで一気に注目が広がりました。

よくある質問

G# は C# を置き換える言語ですか?

いいえ。G# は C# を置き換えるためのものではなく、.NET 上のもう一つの言語選択肢です。マネージドアセンブリへコンパイルし C# と相互運用できるため、既存資産と混在させられます。より小さく予測可能な構文や、Go/Kotlin/Swift 由来の設計を好むチームに向きます。

既存の .NET ライブラリ(NuGet や BCL)は使えますか?

使えます。BCL、NuGet パッケージ、ユーザーコードのいずれも呼び出せ、LINQ・ジェネリクス(角括弧 [])・for-in・P/Invoke などにも対応します。MSBuild と Portable PDB に載るため、dotnet build/run やデバッグもそのままです。

いま本番で使って大丈夫ですか?

プレ 1.0(v0.3)の段階なので、長期互換の保証はありません。相互運用の一部は emit のみで、移行ツールも拡大中です。まずは検証・学習・小規模な実験から始め、更新に追随できる体制で試すのが安全です。

参照元

この記事をシェア

コピーしました

関連記事