C#のnull条件演算子(?.)とは?null安全なアクセス方法を解説
生徒
「C#で、変数がnullのときにエラーにならないようにアクセスする方法ってありますか?」
先生
「ありますよ。C#では?.というnull条件演算子を使えば、安全にアクセスできます。」
生徒
「null条件演算子ってどうやって使うんですか?」
先生
「それでは、null条件演算子の基本的な使い方を見てみましょう!」
1. null条件演算子(?.)とは?
C#の?.は「null条件演算子(null-conditional operator)」と呼ばれます。ひとことで言うと、nullかもしれないオブジェクトに対して、安全にプロパティやメソッドへアクセスするための書き方です。
ふつうは、オブジェクトがnullの状態でperson.Nameのようにアクセスすると、NullReferenceException(ヌル参照例外)が発生してプログラムが止まる原因になります。
そこでperson?.Nameのように書くと、C#が内部で「nullかどうか」を先に確認してくれます。nullではないときだけアクセスし、nullなら例外を出さずにnullとして扱うため、エラー回避と読みやすさの両方に役立ちます。初心者のうちは「落ちやすいnull対策」として覚えると理解しやすいです。
■ 超かんたん例:nullでも落ちないアクセス
class Person
{
public string Name { get; set; }
}
Person person = null;
// null条件演算子を使うと、nullでもエラーにならない
Console.WriteLine(person?.Name);
上の例では、personがnullなので本来なら危険ですが、?.を付けることで例外を防げます。結果として画面には何も表示されません(nullが返るため)。「nullかもしれない変数に触るときは?.」という感覚を持つと、C#のnull安全な書き方が身につきます。
2. null条件演算子の基本的な使い方
ここでは、C#のnull条件演算子?.を「実際にどう書くのか」を、できるだけシンプルな例で確認します。ポイントは、nullかもしれない変数に対して、いきなりプロパティへ触らないことです。
次の例では、PersonクラスのNameプロパティにアクセスしています。
class Person
{
public string Name { get; set; }
}
Person person = null;
Console.WriteLine(person?.Name);
このコードでpersonはnullなので、person.Nameと書くとNullReferenceExceptionになってしまいます。ですが、person?.Nameなら「nullだったらそこで止める」という動きをしてくれるため、エラーを出さずにそのまま処理が進みます。
なお、?.を使った場合は、アクセス結果がnullになる可能性があります。今回の例では、表示される値がない(空っぽに見える)だけなので安心ですが、「画面に何か表示したい」場合は、次のようにデフォルト表示を用意しておくと分かりやすいです。
■ もう一歩だけ:nullのときの表示も用意する
class Person
{
public string Name { get; set; }
}
Person person = null;
// nullなら「未設定」と表示する(初心者でも挙動が追いやすい)
Console.WriteLine(person?.Name ?? "未設定");
personがnullならperson?.Nameはnullになり、その場合は"未設定"が表示されます。こうしておくと、null条件演算子が「落ちないための保険」だと実感しやすくなります。
3. null条件演算子の応用:メソッドの呼び出し
null条件演算子は、プロパティだけでなく、メソッドの呼び出しにも使えます。
class Logger
{
public void Log(string message)
{
Console.WriteLine("ログ: " + message);
}
}
Logger logger = null;
logger?.Log("処理を開始します。");
この例では、loggerがnullであるため、Logメソッドを直接呼ぶとエラーになります。しかしlogger?.Log("...")と書けば、nullかどうかを判断してから実行するため、エラーにならずにスキップされます。
4. null条件演算子の注意点
null条件演算子はとても便利ですが、注意点もあります。例えば、結果がnullになる可能性があるため、値をそのまま使おうとすると別の問題が起きることがあります。
int? length = person?.Name.Length;
この場合、lengthはint?(nullable int型)になり、nullか整数値かのどちらかになります。そのため、length.Valueのようにして取り出す前に、nullチェックをする必要があります。
5. null条件演算子と配列・リストのアクセス
配列やリストにアクセスする時にも、null条件演算子を活用できます。
List<string> words = null;
int? count = words?.Count;
wordsがnullの場合でも、words?.Countと書けばエラーにはならず、countにはnullが入ります。これにより、nullかどうかを先に確認する処理を書く必要がなくなるため、コードがすっきりします。
6. null条件演算子の内部的な動作とは?
裏側では、?.は次のようなif文に書き換えた処理と同じことをしています。
if (person != null)
{
Console.WriteLine(person.Name);
}
このようなコードをいちいち毎回書かなくても、?.を使うだけで同じ動作ができます。可読性(読みやすさ)や保守性(メンテナンスのしやすさ)が向上します。
7. null条件演算子とnull合体演算子の組み合わせ
null条件演算子と一緒によく使われるのが、null合体演算子(??)です。これは、値がnullのときに、代わりのデフォルト値を設定することができます。
string name = person?.Name ?? "未登録";
Console.WriteLine(name);
この例では、person?.Nameがnullだった場合に"未登録"という文字列が代わりに代入されます。
まとめ
C#のnull条件演算子(?.)は、オブジェクトがnullである可能性を考慮したうえで、安全にプロパティやメソッドへアクセスできる便利な演算子です。初心者がつまずきやすいNullReferenceExceptionを避けるための強力な味方といえるでしょう。
従来であればif (obj != null)のように、逐一nullチェックを行っていた処理が、obj?.Propertyのように1行で書けるようになり、コードの可読性や保守性が大幅に向上します。
特にオブジェクトのネストが深い場合や、複雑なデータ構造にアクセスする場合には、null条件演算子の活用が非常に有効です。実際のプロジェクトや日常の開発の中でも、nullチェックの煩雑さを軽減でき、エラーを事前に回避することができるため、安定したプログラム設計に貢献します。
null条件演算子とnull合体演算子の組み合わせ例
null条件演算子(?.)とnull合体演算子(??)はセットで使うことで、null安全かつデフォルト値の設定が簡潔に行えるようになります。以下はその応用例です。
class User
{
public string Nickname { get; set; }
}
User user = null;
string displayName = user?.Nickname ?? "ゲストユーザー";
Console.WriteLine($"表示名:{displayName}");
この例では、userがnullでもNicknameにアクセスしてもエラーが出ず、代わりに??によって「ゲストユーザー」という文字列が表示されるようになっています。
どんな場合でもプログラムが安定して動作するように工夫することは、現場でも非常に重要なスキルです。
メソッド呼び出しとnull条件演算子
プロパティだけでなく、メソッド呼び出し時にもnull条件演算子が使えるということを学びました。
class Notification
{
public void Send(string msg)
{
Console.WriteLine("通知: " + msg);
}
}
Notification notifier = null;
notifier?.Send("処理完了しました。");
このように、nullかどうかを自動で判断しながらメソッドを呼び出すことで、余計なif文を省きつつ、安全なコードを書くことができます。
リストや配列にも使える
null条件演算子は、Listや配列などにも活用できます。例えば次のように書けば、nullチェックをしなくても要素数の取得が安全に行えます。
List<string> fruits = null;
int? count = fruits?.Count;
Console.WriteLine($"果物の数:{count ?? 0}個");
上記のように??を併用することで、nullだった場合に0とする処理もスマートに記述できます。こうした記述方法は、nullに対して強くなるC#コーディング習慣を自然と身につけるのに役立ちます。
日常的に使える考え方を身につけよう
null条件演算子を使いこなすことで、nullの存在を前提とした堅牢なプログラム設計が可能になります。特にユーザーからの入力や外部データなど、nullが混入しやすいシーンでは、nullチェックのコード量が激減するため、保守面でも非常に有利です。
初心者のうちはif (x != null)をたくさん書いてしまいがちですが、簡潔かつ安全なコードに置き換える発想を身につけることが大切です。
生徒
「null条件演算子ってすごく便利ですね。nullチェックしなくていいなんてラクです!」
先生
「そうですね。特に大規模なプログラムになると、nullのチェックが多くなるので、?.で簡潔に書けるのは大きな利点です。」
生徒
「でも、値がnullになるときもあるから、??でフォローしてあげた方が安心ですね。」
先生
「その通り。?.と??を組み合わせて使うと、nullに対してとても強いコードが書けますよ。」
生徒
「よし!これからは?.を活用して、スマートで安全なコードを目指します!」