この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:5
ページ更新者:guest
更新日時:2026-06-11 07:12:00

タイトル: 文法
SEOタイトル: C# 言語基本文法完全ガイド (var/$文字列補間/null安全/records)

この記事の要点
  • C# は 静的型付けint n = 10; / var n = 10; (型推論) いずれも可
  • 文字列補間は $"name = {name}"。複数行は $@"..." または raw string $"""...""" (C# 11+)
  • null 安全演算子: ?. (null 条件) / ?? (null 合体) / ??= (null 代入)
  • C# 9+ で records (不変データクラス) / top-level statements / init-only setters
  • C# 10+ で global using / file-scoped namespace によりボイラープレートが激減

最小プログラム (C# 9+ top-level)

// Program.cs (C# 9+ top-level statements)
Console.WriteLine("Hello, World!");
int n = 10;
Console.WriteLine($"n = {n}");

従来は次のように書く必要がありました:

using System;

namespace HelloApp
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello, World!");
        }
    }
}

変数宣言と型推論

int n = 10;
string s = "hello";
double pi = 3.14;
bool flag = true;
char c = 'A';

// 型推論 (var)
var name = "Taro";        // string
var list = new List<int>{1, 2, 3};  // List<int>
var dict = new Dictionary<string, int>();

// 定数 (const は コンパイル時定数)
const int MAX = 100;

// 読み取り専用 (実行時に決まる)
readonly DateTime startedAt = DateTime.Now;

文字列補間 ($ プレフィックス)

string name = "Taro";
int age = 30;

// $ で補間
string s1 = $"Hello, {name}! Age = {age}";

// 書式指定
double price = 1234.5;
Console.WriteLine($"price = {price:N2}");      // price = 1,234.50
Console.WriteLine($"date = {DateTime.Now:yyyy/MM/dd}");

// 複数行 (verbatim + 補間)
string sql = $@"
    SELECT * FROM users
    WHERE name = '{name}'
      AND age > {age}";

// C# 11+ raw string literals
string json = $"""
    {
      "name": "{name}",
      "age": {age}
    }
    """;

null 安全演算子

string? maybeNull = GetName();   // C# 8+ nullable reference types

// ?. null 条件演算子
int? length = maybeNull?.Length;       // null なら null

// ?? null 合体演算子
string name = maybeNull ?? &quot;anonymous&quot;;

// ??= null 代入演算子
maybeNull ??= &quot;default&quot;;              // null の場合だけ代入

// !  null 抑制 (上級者向け)
int len = maybeNull!.Length;          // 「null じゃないと断言」

// 例
User? user = await db.FindAsync(id);
string city = user?.Address?.City ?? &quot;unknown&quot;;

Pattern Matching (C# 7+)

// is 型パターン
if (obj is string s)
{
    Console.WriteLine(s.Length);
}

// switch 式 (C# 8+)
string category = item switch
{
    Book b when b.Pages > 1000 => "thick",
    Book => "book",
    Music m => $"music ({m.Artist})",
    null => "none",
    _ => "other",
};

// Property pattern (C# 8+)
string description = user switch
{
    { Age: > 18, IsActive: true } => "active adult",
    { Age: <= 18 } => "minor",
    _ => "unknown",
};

// List pattern (C# 11+)
int[] arr = { 1, 2, 3 };
if (arr is [1, _, 3]) { /* 真ん中は何でも */ }

records (C# 9+)

// 不変データクラス
public record User(string Name, int Age);

var u = new User(&quot;Taro&quot;, 30);
Console.WriteLine(u);                   // User { Name = Taro, Age = 30 }
Console.WriteLine(u == new User(&quot;Taro&quot;, 30));  // True (値比較)

// with 式で複製しつつ変更
var older = u with { Age = 31 };

// C# 10+ record struct (値型)
public record struct Point(int X, int Y);

init-only setters / required (C# 9+ / 11+)

public class User
{
    public required string Name { get; init; }   // C# 11+
    public int Age { get; init; }
}

// オブジェクト初期化子で設定後は変更不可
var u = new User { Name = &quot;Taro&quot;, Age = 30 };
// u.Name = &quot;X&quot;;   ❌ コンパイルエラー

// required を忘れるとエラー
var bad = new User { Age = 30 };   // ❌ Name 必須

global using / file-scoped namespace

// GlobalUsings.cs (C# 10+)
global using System;
global using System.Collections.Generic;
global using System.Linq;
// → 全ファイルで自動 using

// MyClass.cs - ファイル全体が namespace 直下
namespace MyApp.Services;

public class UserService
{
    // ...
}

Java / Kotlin との比較

項目C#JavaKotlin
型推論var n = 10var n = 10 (Java 10+)val n = 10
不変readonly / initfinalval
null 安全?. ??Optional?. ?:
文字列補間$&quot;{x}&quot;String.format&quot;${x}&quot;
データクラスrecordrecord (Java 14+)data class
top-level コード✅ C# 9+

例外処理

try
{
    var content = File.ReadAllText(&quot;data.txt&quot;);
}
catch (FileNotFoundException ex) when (ex.FileName.EndsWith(&quot;.txt&quot;))
{
    // when 句で追加条件 (フィルタ)
    Console.WriteLine(&quot;テキストファイルなし&quot;);
}
catch (Exception ex)
{
    Console.WriteLine($&quot;エラー: {ex.Message}&quot;);
    throw;       // 再 throw (スタック維持)
}
finally
{
    // 必ず実行
}

// using 宣言 (C# 8+)
using var file = File.OpenRead(&quot;data.txt&quot;);
// メソッド終了時に自動 Dispose

FAQ

Q: var を使うべきか型を書くべきか?
A: マイクロソフト推奨は「右辺から型が自明な場合 var、API 戻り値などで型が不明瞭なら明示」。チーム規約に従う。

Q: stringString どちらを使う?
A: 同じ型のエイリアス。ローカル変数は小文字 stringString.IsNullOrEmpty のようなクラスメソッド呼び出しは大文字、が慣習。

Q: Nullable Reference Types を有効にすべき?
A: 新規プロジェクトでは <Nullable>enable</Nullable> 推奨。NullReferenceException を激減できます。