C#の省略記法まとめ|var・using・ラムダ・null条件演算子を初心者向けに解説
はじめに
C#には、コードを短く、読みやすく書くための「省略記法」が数多く用意されています。
たとえば、変数宣言で型名を省略できるvar、長い名前空間の記述を省略できるusing、処理を短く書けるラムダ式、nullチェックを簡潔にできるnull条件演算子などがあります。
省略記法を使うと、同じ処理でもコード量を減らせます。ただし、何でも短くすればよいわけではありません。省略しすぎると、かえって「何をしているコードなのか」が分かりにくくなることもあります。
この記事では、C#初心者向けに、よく使われる省略記法をまとめて解説します。var、using、ラムダ式、null条件演算子を中心に、プロパティ、条件分岐、コレクション初期化など、実務でもよく登場する書き方をコード例つきで確認していきましょう。
1. C#の省略記法とは?初心者がまず押さえる全体像
C#の省略記法とは、型名、クラス名、メソッドの記述、nullチェック、代入処理などを、より短い形で書ける構文のことです。
C#はもともと型を明確に書く言語ですが、バージョンアップとともに、冗長な記述を減らすための機能が増えてきました。そのため、現在のC#では、昔ながらの書き方と省略した書き方の両方を見かけます。
初心者のうちは、まず「何が省略されているのか」を理解することが大切です。
1-1. C#で「省略」と呼ばれる書き方の意味
C#における省略とは、本来書くこともできる情報を、コンパイラが推測できる場合に短く書くことを指します。
たとえば、次のようなコードがあります。
C#string name = "Taro";
これは文字列型の変数nameを宣言しています。C#では、右辺の"Taro"を見れば文字列であることが分かるため、次のように書けます。
C#var name = "Taro";
この場合、varを使うことでstringという型名を省略しています。ただし、型がなくなったわけではありません。コンパイル時にはnameはstring型として扱われます。
このように、C#の省略記法は「型や処理を曖昧にするもの」ではなく、「コンパイラが判断できる情報を人間が書かなくてよいようにするもの」です。
1-2. 省略記法を使うメリットと注意点
省略記法を使う主なメリットは、コードが短くなり、読みやすくなることです。
たとえば、長い型名を毎回書くと、処理の本質よりも型名の長さが目立ってしまいます。
C#Dictionary<string, List<int>> scores = new Dictionary<string, List<int>>();
varやターゲット型のnewを使うと、次のように短く書けます。
C#Dictionary<string, List<int>> scores = new();
または、右辺から型が明確な場合は次のようにも書けます。
C#var scores = new Dictionary<string, List<int>>();
コード量が減ると、処理の流れを追いやすくなります。一方で、省略しすぎると、型や処理内容が分かりにくくなる場合があります。
たとえば、次のコードは、GetData()が何を返すのかメソッド名だけでは分かりません。
C#var data = GetData();
このような場合は、あえて型名を書く方が親切です。
C#UserData data = GetData();
省略記法は「短くするため」だけでなく、「読みやすくするため」に使うものだと考えましょう。
1-3. 初心者が混乱しやすい「省略できるもの」と「省略しない方がよいもの」
C#では多くのものを省略できますが、すべてを省略すればよいわけではありません。
省略しやすいものには、次のようなものがあります。
C#var count = 10;
var name = "Taro";
var users = new List<string>();
右辺を見れば型が明確な場合は、varを使っても読みやすさを保てます。
一方で、次のようなコードは注意が必要です。
C#var result = service.Execute();
Execute()の戻り値が分からない場合、読み手はメソッド定義を確認しなければなりません。特に初心者がコードを読むときには、型が明示されていた方が理解しやすいことがあります。
また、ラムダ式や三項演算子も便利ですが、条件や処理が複雑な場合は通常のif文やメソッドに分けた方が読みやすくなります。
省略できるから省略するのではなく、読み手が迷わないかを基準に判断することが大切です。
2. varによる型名の省略
varは、C#の省略記法の中でも特によく使われる機能です。変数宣言時に型名を書かず、右辺の値からコンパイラに型を推論させます。
初心者が最初に覚えたい省略記法のひとつです。
2-1. varとは何か
varは、ローカル変数の型名を省略するためのキーワードです。
次の2つのコードは、ほぼ同じ意味になります。
C#int number = 10;
C#var number = 10;
この場合、右辺の10はint型なので、numberはint型として扱われます。
重要なのは、varを使っても型がなくなるわけではないという点です。C#は静的型付け言語なので、varで宣言した変数にもコンパイル時に明確な型が決まります。
たとえば、次のコードはエラーになります。
C#var number = 10;
number = "hello";
numberは最初にint型として推論されるため、あとから文字列を代入することはできません。
2-2. varを使った基本的な書き方
varは、ローカル変数を宣言するときに使います。
C#var age = 20;
var name = "Yamada";
var isActive = true;
それぞれ、右辺の値から次のように型が推論されます。
C#int age = 20;
string name = "Yamada";
bool isActive = true;
オブジェクト生成でもよく使われます。
C#var user = new User();
var list = new List<string>();
var dictionary = new Dictionary<string, int>();
特に型名が長い場合、varを使うとコードがすっきりします。
C#var users = new Dictionary<string, List<User>>();
ただし、varは「何でも省略できる魔法のキーワード」ではありません。右辺から型が判断できる場合にだけ使えます。
2-3. varを使える場面と使えない場面
varは、メソッド内などのローカル変数で使えます。
C#void Sample()
{
var message = "Hello";
var count = 5;
}
一方で、フィールドやメソッドの戻り値、引数の型としては基本的に使えません。
C#// エラー
var name = "Taro"; // クラス直下のフィールドでは使えない
C#// エラー
var GetName()
{
return "Taro";
}
C#// エラー
void Show(var message)
{
}
また、初期値なしの宣言にも使えません。
C#// エラー
var count;
varは右辺から型を推論するため、初期値がないと型を決められないからです。
次のようにnullだけを代入することもできません。
C#// エラー
var user = null;
nullだけでは、stringなのか、Userなのか、別の参照型なのか判断できないためです。
2-4. varを使うべきケース・避けるべきケース
varを使うべきケースは、右辺を見れば型が明らかな場合です。
C#var user = new User();
var names = new List<string>();
var createdAt = DateTime.Now;
このようなコードでは、型名を書かなくても意味が分かりやすく、冗長さを減らせます。
LINQの結果を受け取る場合にもvarはよく使われます。
C#var activeUsers = users.Where(user => user.IsActive);
LINQでは戻り値の型が長くなることがあるため、varを使うと実用的です。
一方で、戻り値の型が分かりにくいメソッドでは、明示的に型を書く方がよい場合があります。
C#var result = Calculate();
Calculate()がintを返すのか、decimalを返すのか、独自クラスを返すのか分からない場合があります。
このようなときは、次のように書くと読みやすくなります。
C#decimal result = Calculate();
初心者のうちは、「右辺だけで型が分かるならvar」「分かりにくいなら型を書く」と覚えるとよいでしょう。
2-5. varとdynamicの違い
varと混同されやすいものにdynamicがあります。
varは、コンパイル時に型が決まります。
C#var message = "Hello";
message = 123; // エラー
messageはstring型として推論されるため、あとからint型の値は代入できません。
一方、dynamicは実行時に型が決まります。
C#dynamic value = "Hello";
value = 123; // OK
dynamicは柔軟ですが、コンパイル時の型チェックが弱くなります。そのため、存在しないメソッドを呼び出してもコンパイル時にはエラーにならず、実行時にエラーになることがあります。
C#dynamic value = "Hello";
value.NotExists(); // 実行時エラー
varは安全に型名を省略する機能で、dynamicは動的に型を扱う機能です。初心者が通常のC#コードを書く場合は、まずvarを理解し、dynamicは必要な場面だけ使うと考えましょう。
3. usingの省略記法
usingは、C#で名前空間やクラス名、リソース解放処理を簡潔にするために使われます。
一口にusingといっても、いくつかの用途があります。初心者が混乱しやすい部分なので、順番に確認していきましょう。
3-1. usingディレクティブで名前空間を省略する
usingディレクティブは、名前空間の記述を省略するために使います。
たとえば、List<T>を使うには、本来であれば次のように完全修飾名を書くこともできます。
C#System.Collections.Generic.List<string> names = new System.Collections.Generic.List<string>();
しかし、毎回これを書くのは大変です。そこで、ファイルの先頭に次のように書きます。
C#using System.Collections.Generic;
すると、次のように短く書けます。
C#List<string> names = new List<string>();
このように、usingを使うことで名前空間の記述を省略できます。
よく使う例としては、次のようなものがあります。
C#using System;
using System.Collections.Generic;
using System.Linq;
Console、List<T>、LINQのWhereやSelectなどを使うときによく登場します。
3-2. using staticでクラス名を省略する
using staticを使うと、静的メンバーを呼び出すときのクラス名を省略できます。
たとえば、通常はMathクラスのSqrtメソッドを次のように呼び出します。
C#var result = Math.Sqrt(25);
ファイルの先頭に次のように書くと、Math.を省略できます。
C#using static System.Math;
すると、次のように書けます。
C#var result = Sqrt(25);
Console.WriteLineも同じように省略できます。
C#using static System.Console;
C#WriteLine("Hello");
ただし、using staticを使いすぎると、どのクラスのメソッドを呼んでいるのか分かりにくくなることがあります。特に複数のクラスに同じ名前のメソッドがある場合は注意が必要です。
3-3. usingエイリアスで長い型名を短くする
usingエイリアスを使うと、長い型名や名前空間に別名を付けられます。
たとえば、次のように書けます。
C#using StringList = System.Collections.Generic.List<string>;
すると、コード内でStringListという名前を使えます。
C#StringList names = new StringList();
長い型名を何度も書く必要がある場合に便利です。
また、同じ名前のクラスが複数の名前空間に存在する場合にも使えます。
C#using WinFormsTimer = System.Windows.Forms.Timer;
using ThreadingTimer = System.Threading.Timer;
このように別名を付けることで、どちらのTimerを使っているのか明確にできます。
省略というより「分かりやすい名前に置き換える」機能として覚えるとよいでしょう。
3-4. global usingで毎回のusing記述を省略する
global usingを使うと、プロジェクト全体で有効なusingを定義できます。
通常、usingはファイルごとに書きます。
C#using System;
using System.Collections.Generic;
しかし、複数のファイルで毎回同じusingを書くのは面倒です。そこで、共通で使う名前空間を次のように定義できます。
C#global using System;
global using System.Collections.Generic;
global using System.Linq;
これにより、同じプロジェクト内の各ファイルで個別にusingを書かなくても、これらの名前空間を使えるようになります。
global usingは、小規模なコードでは意識しなくても困らないことが多いですが、プロジェクトが大きくなると便利です。
ただし、どの名前空間がどこで有効になっているのか分かりにくくなる場合もあるため、チーム開発ではルールを決めて使うことが大切です。
3-5. using宣言でリソース解放処理を簡潔に書く
usingには、名前空間の省略以外に、リソース解放を自動化する使い方もあります。
ファイルやデータベース接続など、使い終わったら解放が必要なオブジェクトがあります。従来はusingステートメントを使って、次のように書きます。
C#using (var reader = new StreamReader("sample.txt"))
{
var text = reader.ReadToEnd();
Console.WriteLine(text);
}
この書き方では、usingブロックを抜けたタイミングで自動的にDispose()が呼ばれます。
C#では、より短く書けるusing宣言も使えます。
C#using var reader = new StreamReader("sample.txt");
var text = reader.ReadToEnd();
Console.WriteLine(text);
この場合、変数readerのスコープを抜けるタイミングで自動的にリソースが解放されます。
ネストが深くならないため、処理が読みやすくなるのがメリットです。ただし、いつ解放されるのかを理解して使う必要があります。
4. ラムダ式によるメソッド記述の省略
ラムダ式は、処理を短く書くための記法です。特にLINQやイベント処理、コールバック処理でよく使われます。
最初は=>の記号に戸惑うかもしれませんが、慣れるとC#では欠かせない書き方です。
4-1. ラムダ式とは何か
ラムダ式とは、名前のない関数を短く書くための構文です。
基本形は次のようになります。
C#引数 => 処理
たとえば、数値を2倍にする処理は次のように書けます。
C#x => x * 2
これは、「xを受け取り、x * 2を返す処理」という意味です。
通常のメソッドで書くと、次のようになります。
C#int Double(int x)
{
return x * 2;
}
ラムダ式を使うと、メソッド名やreturnなどを省略して、処理の本体だけを簡潔に表せます。
4-2. 匿名メソッドをラムダ式で短く書く
ラムダ式が登場する前は、匿名メソッドを使って処理を書くことがありました。
C#Func<int, int> doubleValue = delegate (int x)
{
return x * 2;
};
これをラムダ式で書くと、次のようになります。
C#Func<int, int> doubleValue = x => x * 2;
かなり短くなりました。
引数が複数ある場合は、丸括弧を使います。
C#Func<int, int, int> add = (x, y) => x + y;
これは、次のようなメソッドと同じような意味です。
C#int Add(int x, int y)
{
return x + y;
}
ラムダ式は、短い処理をその場で渡したいときに便利です。
4-3. 引数の型を省略する書き方
ラムダ式では、引数の型を省略できることが多いです。
たとえば、次のコードではFunc<int, int>によって、引数と戻り値がintであることが分かります。
C#Func<int, int> square = x => x * x;
本来は次のように型を書くこともできます。
C#Func<int, int> square = (int x) => x * x;
しかし、左辺のFunc<int, int>からxがintだと判断できるため、型を省略できます。
LINQでも同じです。
C#var adults = users.Where(user => user.Age >= 20);
usersがList<User>であれば、userはUser型だと推論されます。そのため、ラムダ式の引数に型を書く必要がありません。
ただし、型が推論できない場合や、あえて型を明示したい場合は書くこともできます。
C#Func<int, bool> isEven = (int x) => x % 2 == 0;
4-4. 戻り値やreturnを省略できるケース
ラムダ式では、処理が1つの式だけであれば、returnと波括弧を省略できます。
C#Func<int, int> doubleValue = x => x * 2;
これは、次のように書くこともできます。
C#Func<int, int> doubleValue = x =>
{
return x * 2;
};
短い処理であれば、1行のラムダ式の方が読みやすいことが多いです。
一方で、複数行の処理を書く場合は波括弧とreturnが必要になります。
C#Func<int, int> calculate = x =>
{
var doubled = x * 2;
return doubled + 10;
};
無理に1行にまとめると読みにくくなるため、処理が複雑な場合はブロック形式で書きましょう。
4-5. LINQでよく使うラムダ式の省略例
ラムダ式が特によく使われるのがLINQです。
たとえば、20歳以上のユーザーだけを取り出す場合、次のように書けます。
C#var adults = users.Where(user => user.Age >= 20);
名前だけを取り出す場合はSelectを使います。
C#var names = users.Select(user => user.Name);
条件に合う最初の要素を取得する場合はFirstOrDefaultを使います。
C#var user = users.FirstOrDefault(user => user.Id == 1);
並び替えにもラムダ式を使えます。
C#var sortedUsers = users.OrderBy(user => user.Age);
LINQでは、ラムダ式によって「何を条件にするのか」「何を取り出すのか」を短く表現できます。
ただし、条件が複雑になりすぎる場合は、別メソッドに分けると読みやすくなります。
C#var targets = users.Where(user => IsTargetUser(user));
このようにすると、ラムダ式の中身が短くなり、意図も分かりやすくなります。
5. null条件演算子によるnullチェックの省略
C#では、nullの扱いに注意が必要です。nullのオブジェクトに対してプロパティやメソッドを呼び出すと、例外が発生します。
null条件演算子を使うと、よくあるnullチェックを短く書けます。
5-1. null条件演算子「?.」とは何か
null条件演算子?.は、左側の値がnullでない場合だけ、右側のメンバーにアクセスするための演算子です。
C#var name = user?.Name;
このコードは、userがnullでなければuser.Nameを取得し、userがnullなら結果はnullになります。
従来の書き方では、次のようにnullチェックが必要でした。
C#string name = null;
if (user != null)
{
name = user.Name;
}
null条件演算子を使うと、これを1行で書けます。
C#var name = user?.Name;
?.は、null参照による例外を避けながら、コードを簡潔にできる便利な省略記法です。
5-2. 従来のnullチェックとの比較
従来のnullチェックは、次のように書きます。
C#if (user != null)
{
Console.WriteLine(user.Name);
}
null条件演算子を使うと、次のように書けます。
C#Console.WriteLine(user?.Name);
userがnullの場合、user?.Nameはnullになります。Console.WriteLineにnullが渡されても、通常は例外にはなりません。
メソッド呼び出しでも使えます。
C#user?.SendEmail();
これは、次のような処理と似ています。
C#if (user != null)
{
user.SendEmail();
}
短く書けるだけでなく、「nullなら何もしない」という意図が分かりやすくなります。
5-3. メソッド呼び出し・プロパティ参照での使い方
null条件演算子は、プロパティ参照でよく使われます。
C#var email = user?.Email;
ネストしたオブジェクトにも使えます。
C#var city = user?.Address?.City;
この場合、userがnullでも、Addressがnullでも、結果はnullになります。
メソッド呼び出しにも使えます。
C#user?.UpdateLastLogin();
配列やリストの要素アクセスには?[]を使えます。
C#var first = names?[0];
namesがnullの場合、例外ではなくnullになります。
イベント呼び出しでもよく使われます。
C#Changed?.Invoke(this, EventArgs.Empty);
これは、イベントに購読者がいる場合だけ呼び出す書き方です。
5-4. null合体演算子「??」との組み合わせ
null条件演算子は、null合体演算子??と組み合わせるとさらに便利です。
??は、左辺がnullの場合に右辺の値を使う演算子です。
C#var name = user?.Name ?? "名前なし";
このコードでは、userがnullの場合、またはuser.Nameがnullの場合に、"名前なし"が使われます。
従来の書き方にすると、次のような処理に近くなります。
C#string name;
if (user != null && user.Name != null)
{
name = user.Name;
}
else
{
name = "名前なし";
}
?.と??を組み合わせることで、nullチェックと初期値設定を短く書けます。
他にも、次のような使い方ができます。
C#var count = users?.Count ?? 0;
usersがnullなら0、そうでなければusers.Countを取得します。
5-5. null条件演算子を使うときの注意点
null条件演算子は便利ですが、使いどころに注意が必要です。
まず、?.を使うと結果がnullになる可能性があります。
C#var length = user?.Name.Length;
この場合、userがnullならlengthはnullになります。Nameがnullの場合も考慮が必要です。
安全に書くなら、次のようにします。
C#var length = user?.Name?.Length ?? 0;
また、nullであることが異常な状態であれば、?.で黙って処理を続けるよりも、例外を発生させた方がよい場合もあります。
C#user?.Save();
このコードは、userがnullなら何もしません。しかし、本来userがnullであってはいけない場面では、不具合に気づきにくくなる可能性があります。
null条件演算子は「nullでも問題ない場面」で使うのが基本です。
6. プロパティ・メソッドで使える省略記法
C#では、クラスのプロパティやメソッドも簡潔に書けます。特に、自動実装プロパティや式形式メンバーはよく使われる省略記法です。
6-1. 自動実装プロパティでget/setを簡潔に書く
通常のプロパティは、フィールドを用意してgetとsetを実装します。
C#private string name;
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
自動実装プロパティを使うと、次のように短く書けます。
C#public string Name { get; set; }
C#ではこの書き方が非常によく使われます。
読み取り専用にしたい場合は、setを外したり、private setにしたりできます。
C#public string Name { get; private set; }
初期値も設定できます。
C#public string Name { get; set; } = "未設定";
単純に値を保持するだけのプロパティであれば、自動実装プロパティを使うのが一般的です。
6-2. 式形式メンバーでメソッドを1行に省略する
式形式メンバーを使うと、短いメソッドやプロパティを1行で書けます。
通常のメソッドは次のように書きます。
C#public int Add(int x, int y)
{
return x + y;
}
式形式メンバーを使うと、次のようになります。
C#public int Add(int x, int y) => x + y;
returnと波括弧を省略できるため、短い処理に向いています。
読み取り専用プロパティにも使えます。
C#public string FullName => FirstName + " " + LastName;
これは、次のようなプロパティと似た意味です。
C#public string FullName
{
get
{
return FirstName + " " + LastName;
}
}
単純な計算や値の取得であれば、式形式メンバーを使うとコードがすっきりします。
6-3. コンストラクターやプロパティ初期化の省略例
C#では、オブジェクト生成時の初期化も簡潔に書けます。
通常、コンストラクターで値を設定する場合は次のように書きます。
C#public class User
{
public string Name { get; }
public User(string name)
{
Name = name;
}
}
単純な初期化であれば、プロパティ初期化子を使えます。
C#public string Name { get; set; } = "Guest";
オブジェクト初期化子を使うと、生成後の代入処理をまとめて書けます。
C#var user = new User
{
Name = "Taro",
Age = 20
};
これは、次のように書くのと似ています。
C#var user = new User();
user.Name = "Taro";
user.Age = 20;
オブジェクト初期化子を使うと、どの値で初期化されているかがひとまとまりで分かります。
また、型が左辺から分かる場合は、ターゲット型のnewを使って型名を省略できます。
C#User user = new()
{
Name = "Taro",
Age = 20
};
6-4. record型で定型コードを省略する
record型を使うと、データを表すクラスの定型コードを大きく省略できます。
たとえば、名前と年齢を持つデータを作る場合、通常のクラスでは次のように書きます。
C#public class User
{
public string Name { get; }
public int Age { get; }
public User(string name, int age)
{
Name = name;
Age = age;
}
}
recordを使うと、次のように短く書けます。
C#public record User(string Name, int Age);
これだけで、プロパティ、コンストラクター、値の比較などが自動的に用意されます。
C#var user1 = new User("Taro", 20);
var user2 = new User("Taro", 20);
Console.WriteLine(user1 == user2); // True
通常のクラスでは参照が同じかどうかを比較しますが、recordは値を中心に扱いたいデータに向いています。
DTOや設定値、変更しにくいデータを表す場合に便利です。
7. 条件分岐・代入で使える省略記法
C#では、条件分岐や代入も短く書けます。三項演算子、null合体演算子、パターンマッチングなどを使うと、よくある処理を簡潔に表現できます。
7-1. 三項演算子でif文を短く書く
三項演算子は、条件によって値を切り替えるときに使います。
基本形は次のとおりです。
C#条件 ? trueの場合の値 : falseの場合の値
たとえば、年齢によって表示名を変える場合、if文では次のように書けます。
C#string label;
if (age >= 20)
{
label = "成人";
}
else
{
label = "未成年";
}
三項演算子を使うと、次のように1行で書けます。
C#var label = age >= 20 ? "成人" : "未成年";
単純な条件分岐であれば、三項演算子は読みやすく便利です。
ただし、条件が複雑な場合や、三項演算子を入れ子にする場合は読みにくくなります。
C#var label = score >= 80 ? "A" : score >= 60 ? "B" : "C";
このような場合は、通常のif文やswitch式を使った方が分かりやすいことがあります。
7-2. null合体演算子「??」で初期値を簡潔に指定する
null合体演算子??は、左辺がnullでなければ左辺を使い、nullであれば右辺を使う演算子です。
C#var displayName = name ?? "ゲスト";
このコードでは、nameがnullでなければnameを使い、nullなら"ゲスト"を使います。
従来のif文で書くと、次のようになります。
C#string displayName;
if (name != null)
{
displayName = name;
}
else
{
displayName = "ゲスト";
}
??を使うと、null時の初期値を簡潔に指定できます。
メソッドの戻り値にもよく使います。
C#return userName ?? "unknown";
null条件演算子と組み合わせることも多いです。
C#var city = user?.Address?.City ?? "未設定";
このように、nullの可能性がある値を安全に扱うときに便利です。
7-3. null合体代入演算子「??=」の使い方
null合体代入演算子??=は、左辺がnullの場合だけ右辺を代入する演算子です。
C#name ??= "ゲスト";
これは、次のコードと似た意味です。
C#if (name == null)
{
name = "ゲスト";
}
リストの初期化でもよく使えます。
C#items ??= new List<string>();
items.Add("Apple");
itemsがnullなら新しいリストを作り、すでに値が入っていればそのまま使います。
設定値の初期化にも便利です。
C#config.ConnectionString ??= "DefaultConnection";
ただし、左辺が代入可能な変数やプロパティである必要があります。単なる計算結果には使えません。
7-4. パターンマッチングで条件判定を簡潔にする
パターンマッチングを使うと、型チェックや条件判定を簡潔に書けます。
従来の型チェックでは、次のように書くことがありました。
C#if (obj is string)
{
string text = (string)obj;
Console.WriteLine(text.Length);
}
パターンマッチングを使うと、型チェックと変数宣言を同時にできます。
C#if (obj is string text)
{
Console.WriteLine(text.Length);
}
nullチェックにも使えます。
C#if (user is not null)
{
Console.WriteLine(user.Name);
}
条件を組み合わせることもできます。
C#if (age is >= 20)
{
Console.WriteLine("成人です");
}
switch式を使うと、条件ごとの値を短く書けます。
C#var label = score switch
{
>= 80 => "A",
>= 60 => "B",
_ => "C"
};
パターンマッチングは、複雑な条件分岐を読みやすく整理できる便利な省略記法です。
8. コレクション・配列で使える省略記法
配列やリスト、オブジェクトの初期化でも、省略記法はよく使われます。特に、コレクション初期化子とオブジェクト初期化子は実務でも頻繁に登場します。
8-1. コレクション初期化子でAdd処理を省略する
通常、リストに要素を追加する場合は、次のようにAddを何度も呼び出します。
C#var names = new List<string>();
names.Add("Taro");
names.Add("Hanako");
names.Add("Jiro");
コレクション初期化子を使うと、次のように短く書けます。
C#var names = new List<string>
{
"Taro",
"Hanako",
"Jiro"
};
内部的にはAddが呼び出されますが、コード上では要素をまとめて書けます。
辞書でも使えます。
C#var scores = new Dictionary<string, int>
{
{ "Taro", 90 },
{ "Hanako", 85 },
{ "Jiro", 70 }
};
また、インデックス初期化子を使うと、次のようにも書けます。
C#var scores = new Dictionary<string, int>
{
["Taro"] = 90,
["Hanako"] = 85,
["Jiro"] = 70
};
初期データが分かりやすくまとまるため、読みやすいコードになります。
8-2. オブジェクト初期化子で代入処理を省略する
オブジェクト初期化子を使うと、オブジェクト生成後のプロパティ代入をまとめて書けます。
通常の書き方は次のようになります。
C#var user = new User();
user.Name = "Taro";
user.Age = 20;
オブジェクト初期化子を使うと、次のように書けます。
C#var user = new User
{
Name = "Taro",
Age = 20
};
どのプロパティにどの値を設定しているかが、ひと目で分かります。
ネストしたオブジェクトにも使えます。
C#var user = new User
{
Name = "Taro",
Address = new Address
{
City = "Tokyo",
ZipCode = "100-0001"
}
};
初期化処理がまとまるため、コンストラクターを増やしすぎずに済む場合もあります。
ただし、必ず設定すべき値がある場合は、コンストラクターやrequiredプロパティを使って、未設定を防ぐ設計も考えましょう。
8-3. 配列・リストの型推論による省略
配列では、右辺から型が推論できる場合に型名を省略できます。
通常は次のように書きます。
C#int[] numbers = new int[] { 1, 2, 3 };
次のように短く書けます。
C#int[] numbers = { 1, 2, 3 };
varを使う場合は、次のように書けます。
C#var numbers = new[] { 1, 2, 3 };
この場合、numbersはint[]として推論されます。
リストでもvarを使って型名を省略できます。
C#var names = new List<string> { "Taro", "Hanako" };
左辺で型が分かる場合は、ターゲット型のnewも使えます。
C#List<string> names = new() { "Taro", "Hanako" };
型名の重複を避けられるため、長い型を扱うときに便利です。
8-4. インデックス・範囲演算子で要素指定を短く書く
C#では、末尾からの位置を指定するインデックス演算子^と、範囲を指定する範囲演算子..が使えます。
通常、配列の最後の要素を取得するには次のように書きます。
C#var last = numbers[numbers.Length - 1];
^を使うと、次のように短く書けます。
C#var last = numbers[^1];
^1は末尾から1番目を意味します。
範囲を取り出す場合は..を使います。
C#var firstThree = numbers[..3];
これは、先頭からインデックス3の手前までを取得します。
途中から最後までを取得する場合は次のように書きます。
C#var fromSecond = numbers[1..];
範囲を指定することで、部分配列の取得を簡潔に書けます。
C#var middle = numbers[1..4];
ただし、範囲外のインデックスを指定すると例外が発生するため、配列やリストの長さには注意が必要です。
9. C#の省略記法を使うときのベストプラクティス
C#の省略記法は便利ですが、使い方を間違えると可読性を下げる原因になります。大切なのは、短さよりも分かりやすさです。
9-1. 読みやすさを優先して使う
省略記法を使うときは、まず読みやすいかどうかを考えましょう。
たとえば、次のコードは分かりやすい例です。
C#var user = new User();
var names = new List<string>();
右辺を見れば型が分かるため、varを使っても問題ありません。
一方で、次のコードは少し分かりにくい場合があります。
C#var result = repository.Find(id);
Findの戻り値がUserなのか、User?なのか、リストなのか分からない場合があります。
このようなときは、型を明示すると読みやすくなります。
C#User? result = repository.Find(id);
省略記法は、読み手が迷わない場合に使うのが基本です。
9-2. チーム開発ではコーディング規約に合わせる
チーム開発では、自分が読みやすいと思う書き方よりも、チームのルールに合わせることが大切です。
たとえば、varについてはチームによって方針が分かれます。
C#var user = new User();
このように積極的にvarを使うチームもあれば、プリミティブ型では明示するチームもあります。
C#int count = 10;
string name = "Taro";
また、using staticやglobal usingは便利ですが、使いすぎるとコードの見通しが悪くなる場合があります。そのため、プロジェクト全体でどこまで使うかを決めておくと安心です。
省略記法は個人の好みが出やすい部分なので、チームで統一することが重要です。
9-3. 省略しすぎて可読性が下がる例
省略記法を使いすぎると、コードが短くても分かりにくくなることがあります。
たとえば、次のコードを見てみましょう。
C#var x = a?.B?.C ?? d ? e : f;
短くは書けていますが、何を判定して何を返しているのか分かりにくいです。
また、ラムダ式を複雑にしすぎる例もあります。
C#var result = users
.Where(u => u.IsActive && u.Age >= 20 && u.Orders.Any(o => o.Total > 10000))
.Select(u => new { u.Name, Count = u.Orders.Count(o => o.Total > 10000) });
処理が複雑な場合は、条件をメソッドに分けると読みやすくなります。
C#var result = users
.Where(user => IsImportantUser(user))
.Select(user => CreateUserSummary(user));
省略記法は便利ですが、読み手に考えさせるコードになっていないか注意しましょう。
9-4. 初心者が段階的に覚えるおすすめ順
初心者がC#の省略記法を覚えるなら、次の順番がおすすめです。
まずはvarを覚えましょう。変数宣言で頻繁に使うため、最初に理解しておくとコードが読みやすくなります。
次に、usingディレクティブを理解します。名前空間の省略はC#の基本なので、SystemやSystem.Collections.Genericなどの意味を押さえておくとよいでしょう。
その次に、null条件演算子?.とnull合体演算子??を覚えます。nullチェックは実務でよく出てくるため、早めに慣れておくと便利です。
その後、ラムダ式とLINQを学ぶと、C#らしい書き方ができるようになります。
最後に、record型、パターンマッチング、範囲演算子などを少しずつ覚えるとよいでしょう。
一度に全部覚える必要はありません。まずはコードを読めるようになり、次に自分で使えるようになることを目指しましょう。
10. C#省略記法のよくある質問
ここでは、C#の省略記法について初心者が疑問に思いやすいポイントをまとめます。
10-1. C#で型名を省略するには?
C#で型名を省略する代表的な方法はvarです。
C#var name = "Taro";
var age = 20;
var users = new List<User>();
右辺から型が分かる場合、コンパイラが型を推論してくれます。
ただし、varはローカル変数で使うものであり、フィールド、メソッドの戻り値、引数の型などには基本的に使えません。
また、var user = null;のように、型を推論できない書き方もできません。
型名を省略しても型チェックは行われるため、varは安全に使える省略記法です。
10-2. usingはどこまで省略できる?
usingを使うと、名前空間の記述を省略できます。
C#using System.Collections.Generic;
このように書けば、次のようにList<T>を短く使えます。
C#List<string> names = new List<string>();
using staticを使えば、静的メンバーのクラス名も省略できます。
C#using static System.Console;
WriteLine("Hello");
global usingを使えば、プロジェクト全体で共通のusingを定義できます。
ただし、省略しすぎると、どの名前空間やクラスから来たメンバーなのか分かりにくくなる場合があります。特にusing staticやglobal usingは、使いどころを決めておくとよいでしょう。
10-3. ラムダ式の=>は何を省略している?
ラムダ式の=>は、引数と処理をつなぐ記号です。
C#x => x * 2
これは、「xを受け取って、x * 2を返す処理」を表します。
通常のメソッドで書くと、次のようになります。
C#int Double(int x)
{
return x * 2;
}
ラムダ式では、メソッド名、波括弧、return、引数の型などを省略できる場合があります。
C#Func<int, int> doubleValue = x => x * 2;
LINQでは、条件や変換処理を渡すためによく使われます。
C#var adults = users.Where(user => user.Age >= 20);
10-4. nullチェックを短く書くには?
nullチェックを短く書くには、null条件演算子?.やnull合体演算子??を使います。
C#var name = user?.Name;
userがnullでなければNameを取得し、nullなら結果はnullになります。
初期値を指定したい場合は、??を組み合わせます。
C#var name = user?.Name ?? "名前なし";
これは、userまたはuser.Nameがnullの場合に"名前なし"を使う書き方です。
nullの場合だけ代入したい場合は、??=を使えます。
C#name ??= "ゲスト";
nullチェックは省略できますが、nullであることが不自然な場面では、あえて例外を発生させた方がよい場合もあります。
10-5. 省略記法は初心者でも使ってよい?
省略記法は初心者でも使って問題ありません。
ただし、最初は「何が省略されているのか」を理解しながら使うことが大切です。
たとえば、varを使うときは、実際にどの型として扱われているかを意識しましょう。
C#var count = 10; // int
var name = "Taro"; // string
var user = new User(); // User
ラムダ式も、通常のメソッドで書いた場合と比較すると理解しやすくなります。
C#Func<int, int> doubleValue = x => x * 2;
省略記法は、慣れるとC#のコードを読み書きするうえで非常に便利です。ただし、無理にすべてを短く書こうとせず、読みやすさを優先しましょう。
まとめ
C#には、コードを簡潔に書くための省略記法が数多く用意されています。
varを使えば、右辺から型が分かる場合に型名を省略できます。usingを使えば、名前空間やクラス名の記述を短くできます。ラムダ式を使えば、短い処理や条件をその場で簡潔に表現できます。null条件演算子?.やnull合体演算子??を使えば、nullチェックや初期値設定をすっきり書けます。
また、自動実装プロパティ、式形式メンバー、三項演算子、コレクション初期化子、オブジェクト初期化子、パターンマッチング、record型なども、C#でよく使われる省略記法です。
ただし、省略記法は「短く書くこと」だけが目的ではありません。大切なのは、コードを読む人にとって分かりやすいかどうかです。
右辺から型が明らかな場合はvarを使い、処理が短い場合はラムダ式や式形式メンバーを使う。nullでも問題ない場面では?.や??を使う。このように、状況に合わせて使い分けることが重要です。
初心者のうちは、まずvar、using、null条件演算子、ラムダ式の順に覚えるとよいでしょう。少しずつ使いながら、C#らしい簡潔で読みやすいコードを書けるようになっていきましょう。

