C#のnot演算子とは?使い方・否定条件・!=との違いを初心者向けに徹底解説

はじめに

C#で条件を否定したいとき、「notってどう書くの?」「!!=は何が違うの?」「is not nullはどういう意味?」と迷うことがあります。

特に、他のプログラミング言語でnotを使ったことがある人は、C#でもそのまま次のように書けると思うかもしれません。

C#
if (not isValid)
{
// これはC#では基本的に書けない
}

しかし、C#ではPythonのようにnotを単独の論理否定演算子として使うわけではありません。

C#で否定を表す代表的な書き方は、主に次の3つです。

C#
!isValid
C#
value is not null
C#
x != y

どれも「否定」に関係していますが、意味や使う場面は異なります。

この記事では、C#のnot演算子について、初心者にもわかりやすく、!is not!=の違いを整理しながら解説します。

1. C#のnot演算子とは?まず結論から理解しよう

C#で「not演算子」と呼ばれるものを理解するには、まず次の結論を押さえるとわかりやすいです。

C#では、bool値を否定する場合は!を使います。

C#
bool isValid = false;

if (!isValid)
{
Console.WriteLine("有効ではありません");
}

一方で、C#のnotは、主にパターンマッチングで使うキーワードです。

C#
object? value = "Hello";

if (value is not null)
{
Console.WriteLine("nullではありません");
}

つまり、C#で「not」と検索している人が知りたい内容は、多くの場合、次のどれかです。

  • !の使い方

  • is not nullの使い方

  • !=との違い

  • 否定条件の書き方

  • nullチェックの正しい書き方

それぞれの違いを順番に見ていきましょう。

1-1. C#で「not」と検索した人が知りたいこと

C#で「not」と検索する人は、おそらく次のような疑問を持っています。

「C#で条件を否定するにはどう書くのか」

notというキーワードは使えるのか」

!は何を意味するのか」

is not null!= nullは何が違うのか」

!=もnotの一種なのか」

C#では、否定の書き方が1つだけではありません。そのため、最初は混乱しやすいです。

たとえば、「ログインしていない場合」を表すコードは次のように書けます。

C#
bool isLoggedIn = false;

if (!isLoggedIn)
{
Console.WriteLine("ログインしていません");
}

また、「値がnullではない場合」は次のように書けます。

C#
string? name = "Taro";

if (name is not null)
{
Console.WriteLine(name);
}

さらに、「2つの値が等しくない場合」は次のように書けます。

C#
int a = 10;
int b = 20;

if (a != b)
{
Console.WriteLine("aとbは等しくありません");
}

どれも否定に関係していますが、使い方は別物です。

1-2. C#には主に2種類の「否定」がある

C#の否定は、大きく分けると次の2種類があります。

1つ目は、bool式を反転する否定です。

C#
!isActive

これは、truefalseに、falsetrueに反転します。

2つ目は、パターンに一致しないことを表す否定です。

C#
value is not null

これは、「valueがnullパターンに一致しない」、つまり「valueはnullではない」という意味です。

さらに、比較演算子として!=もあります。

C#
x != y

これは「xとyが等しくない」という比較です。

初心者のうちは、次のように考えると整理しやすいです。

C#
!条件

これは「条件ではない」。

C#
 is not パターン

これは「値がそのパターンではない」。

C#
左辺 != 右辺

これは「左辺と右辺が等しくない」。

この3つを分けて理解することが大切です。

1-3. 初心者が混同しやすい「!」「not」「!=」の違い

C#で混同しやすい否定の書き方を簡単にまとめると、次のようになります。

!は、bool値を反転する演算子です。

C#
if (!isEnabled)
{
Console.WriteLine("無効です");
}

notは、パターンマッチングで使うキーワードです。

C#
if (value is not null)
{
Console.WriteLine("nullではありません");
}

!=は、左右の値が等しくないことを調べる比較演算子です。

C#
if (status != "OK")
{
Console.WriteLine("OKではありません");
}

それぞれ似ていますが、使える場所が違います。

たとえば、次のようにnotだけをbool変数の前に書くことはできません。

C#
bool isActive = true;

// エラーになる
if (not isActive)
{
}

C#でbool値を否定したい場合は、次のように!を使います。

C#
if (!isActive)
{
Console.WriteLine("アクティブではありません");
}

1-4. この記事でわかること

この記事を読むと、次の内容がわかります。

C#で条件を否定するときに使う!の基本がわかります。

is not nullの意味と使い方がわかります。

!is not!=の違いがわかります。

nullチェックの書き方を判断できるようになります。

否定条件を読みやすく書くコツがわかります。

練習問題を通して、C#のnot演算子に関する理解を確認できます。

2. C#の否定演算子「!」の基本

C#で最も基本的な否定は、!を使った書き方です。

!は「論理否定演算子」と呼ばれます。

bool値に対して使い、値を反転します。

C#
bool result = true;

Console.WriteLine(!result); // False

2-1. 「!」はbool値を反転する単項論理否定演算子

!は、1つの値に対して使う演算子です。

このように、値の前に付けます。

C#
!条件

たとえば、次のコードを見てください。

C#
bool isCompleted = false;

bool notCompleted = !isCompleted;

Console.WriteLine(notCompleted); // True

isCompletedfalseです。

そこに!を付けると、trueになります。

つまり、!isCompletedは「完了していない」という意味になります。

2-2. trueをfalseに、falseをtrueにする仕組み

!は、bool値を次のように反転します。

C#
!true  // false
!false // true

実際のコードで確認してみましょう。

C#
Console.WriteLine(!true);  // False
Console.WriteLine(!false); // True

変数に対して使う場合も同じです。

C#
bool hasError = true;

Console.WriteLine(!hasError); // False

hasErrorは「エラーがある」という意味です。

!hasErrorは「エラーがない」という意味になります。

2-3. if文で使う基本構文

!は、if文の条件でよく使います。

C#
bool isLogin = false;

if (!isLogin)
{
Console.WriteLine("ログインしてください");
}

このコードでは、isLoginfalseの場合に処理が実行されます。

!isLoginは「ログインしていない」という意味です。

もう1つ例を見てみましょう。

C#
bool hasPermission = false;

if (!hasPermission)
{
Console.WriteLine("権限がありません");
}

hasPermissionは「権限がある」という意味です。

!hasPermissionは「権限がない」という意味になります。

否定条件を読むときは、変数名の前に「〜ではない」と付けると理解しやすいです。

2-4. 変数・メソッドの戻り値に対して使う例

!は、bool変数だけでなく、boolを返すメソッドにも使えます。

C#
static bool IsAdult(int age)
{
return age >= 18;
}

int age = 15;

if (!IsAdult(age))
{
Console.WriteLine("未成年です");
}

IsAdult(age)は、年齢が18歳以上ならtrueを返します。

そこに!を付けることで、「成人ではない場合」という条件になります。

別の例です。

C#
static bool ExistsUser(string userName)
{
return userName == "admin";
}

string inputName = "guest";

if (!ExistsUser(inputName))
{
Console.WriteLine("ユーザーが存在しません");
}

ExistsUser(inputName)falseの場合、!ExistsUser(inputName)trueになります。

そのため、「ユーザーが存在しない場合」の処理を書けます。

2-5. 「!」を読むときの考え方

!を読むときは、次のように考えるとわかりやすいです。

C#
if (!isValid)

これは「isValidではない場合」です。

つまり、「有効ではない場合」と読めます。

C#
if (!hasData)

これは「hasDataではない場合」です。

つまり、「データがない場合」と読めます。

C#
if (!CanSave())

これは「CanSave()ではない場合」です。

つまり、「保存できない場合」と読めます。

ただし、否定が増えすぎると読みにくくなります。

C#
if (!isNotReady)
{
}

このように、変数名の中にも否定があり、さらに!も付いていると意味がわかりにくくなります。

この場合は、できるだけ肯定形の変数名を使うと読みやすくなります。

C#
bool isReady = true;

if (isReady)
{
Console.WriteLine("準備できています");
}

3. C#のnotパターンとは?「is not」の使い方

C#には、notというキーワードがあります。

ただし、notは単独でbool値を否定する演算子ではありません。

主にパターンマッチングの中で使います。

代表的な書き方が、次のis notです。

C#
if (value is not null)
{
Console.WriteLine("valueはnullではありません");
}

これは、C#で非常によく使われるnullチェックの書き方です。

3-1. C#のnotはパターンマッチングで使うキーワード

C#のnotは、パターンマッチングにおける否定パターンです。

パターンマッチングとは、値が特定の形や条件に一致するかを判定する仕組みです。

たとえば、次のコードでは、valuestring型かどうかを判定しています。

C#
object value = "Hello";

if (value is string)
{
Console.WriteLine("文字列です");
}

これを否定すると、次のようになります。

C#
object value = 123;

if (value is not string)
{
Console.WriteLine("文字列ではありません");
}

value is not stringは、「valueがstring型ではない」という意味です。

ここで使われているnotは、stringというパターンを否定しています。

3-2. 「is not null」でnullではないことを判定する

C#でよく使われるのが、is not nullです。

C#
string? name = "Taro";

if (name is not null)
{
Console.WriteLine(name.Length);
}

name is not nullは、「nameがnullではない」という意味です。

これにより、nullではない場合だけ処理できます。

nullチェックには、次のように!= nullを使う書き方もあります。

C#
if (name != null)
{
Console.WriteLine(name.Length);
}

どちらも多くの場合は同じ目的で使えます。

ただし、is not nullはパターンマッチングの構文であり、「nullパターンではない」と明確に読めるため、最近のC#ではよく使われます。

3-3. 型チェックで使う「is not 型名」

is notは、型チェックにも使えます。

C#
object value = 100;

if (value is not string)
{
Console.WriteLine("valueは文字列ではありません");
}

このコードでは、valuestring型ではない場合に処理が実行されます。

逆に、特定の型である場合は次のように書きます。

C#
if (value is string)
{
Console.WriteLine("valueは文字列です");
}

さらに、型チェックと変数宣言を組み合わせることもできます。

C#
object value = "Hello";

if (value is string text)
{
Console.WriteLine(text.Length);
}

この場合、valuestring型なら、textという変数として使えます。

is notと組み合わせる場合は、次のような書き方がよく使われます。

C#
object value = 123;

if (value is not string)
{
Console.WriteLine("文字列以外です");
}

3-4. switch式・switch文で使うnotパターン

notパターンは、if文だけでなく、switch式やswitch文でも使えます。

たとえば、switch式でnullではない場合を判定できます。

C#
string? name = "Taro";

string message = name switch
{
not null => "名前が入力されています",
null => "名前が入力されていません"
};

Console.WriteLine(message);

このコードでは、nameがnullでなければnot nullに一致します。

型チェックと組み合わせることもできます。

C#
object value = 123;

string result = value switch
{
not string => "文字列ではありません",
string => "文字列です"
};

Console.WriteLine(result);

ただし、この例ではnot stringが先にあるため、文字列以外がすべて一致します。

switchでは、上から順番にパターンが評価されるため、順番にも注意が必要です。

3-5. and・or・notを組み合わせた条件指定

C#のパターンマッチングでは、notだけでなく、andorも使えます。

たとえば、数値の範囲を判定するコードです。

C#
int score = 85;

if (score is >= 0 and <= 100)
{
Console.WriteLine("有効な点数です");
}

これは、「scoreが0以上かつ100以下」という意味です。

notを使うと、範囲外を表せます。

C#
int score = 120;

if (score is not (>= 0 and <= 100))
{
Console.WriteLine("点数が範囲外です");
}

このコードは、「scoreが0以上100以下ではない場合」という意味です。

orを使う例も見てみましょう。

C#
string role = "guest";

if (role is "admin" or "manager")
{
Console.WriteLine("管理権限があります");
}

notandorを使うと、条件を自然な文章に近い形で書けます。

ただし、複雑にしすぎると読みにくくなるため、初心者のうちはシンプルな使い方から覚えるのがおすすめです。

4. 「!」と「is not」の違い

C#の否定で特に混同しやすいのが、!is notです。

どちらも否定を表しますが、役割が違います。

!は、bool式を否定します。

C#
!isValid

is notは、パターンに一致しないことを判定します。

C#
value is not null

この違いを理解すると、C#のnot演算子まわりで迷いにくくなります。

4-1. 「!」はbool式を否定する

!は、bool値に対して使います。

C#
bool isValid = false;

if (!isValid)
{
Console.WriteLine("有効ではありません");
}

isValidはbool型です。

そのため、!isValidと書けます。

メソッドの戻り値がboolの場合も同じです。

C#
if (!File.Exists("sample.txt"))
{
Console.WriteLine("ファイルが存在しません");
}

File.Exists("sample.txt")はboolを返します。

そこに!を付けることで、「ファイルが存在しない場合」という意味になります。

4-2. 「is not」はパターンに一致しないことを判定する

is notは、値が特定のパターンに一致しないことを表します。

C#
object value = 123;

if (value is not string)
{
Console.WriteLine("文字列ではありません");
}

この場合、stringという型パターンに一致しないかどうかを判定しています。

nullチェックでも使えます。

C#
string? name = "Taro";

if (name is not null)
{
Console.WriteLine(name);
}

これは、「nameがnullパターンに一致しない」という意味です。

つまり、nameはnullではありません。

4-3. nullチェックではどちらを使うべきか

nullチェックでは、主に次の書き方があります。

C#
if (name != null)
{
}
C#
if (name is not null)
{
}

また、!を使って次のように書くこともあります。

C#
if (!(name is null))
{
}

しかし、これは少し読みにくいです。

初心者には、次のどちらかがおすすめです。

C#
if (name is not null)
{
}

または、

C#
if (name != null)
{
}

最近のC#らしく、意図を明確に書きたい場合はis not nullが読みやすいです。

特に、パターンマッチングを使うコードではis not nullのほうが自然です。

一方で、単純な比較として書きたい場合は!= nullでも問題ありません。

4-4. 可読性の違い

!は短く書けますが、複雑な条件では読みにくくなることがあります。

C#
if (!(age >= 18))
{
Console.WriteLine("18歳未満です");
}

このコードは間違いではありません。

しかし、次のように書いたほうが直感的です。

C#
if (age < 18)
{
Console.WriteLine("18歳未満です");
}

is notは文章に近い形で読めるため、nullチェックや型チェックでは読みやすくなります。

C#
if (user is not null)
{
Console.WriteLine("ユーザーが存在します");
}

これは「user is not null」、つまり「userはnullではない」とそのまま読めます。

4-5. 初心者におすすめの使い分け

初心者は、次のように使い分けるとよいです。

bool変数やboolを返すメソッドを否定するときは!を使います。

C#
if (!isSuccess)
{
Console.WriteLine("成功していません");
}

nullではないことを判定するときはis not nullを使います。

C#
if (user is not null)
{
Console.WriteLine("ユーザーが見つかりました");
}

値が等しくないことを比較するときは!=を使います。

C#
if (status != "OK")
{
Console.WriteLine("正常ではありません");
}

この3つを分けて覚えるだけで、C#の否定条件はかなり理解しやすくなります。

5. 「not」と「!=」の違い

C#で「not」と一緒に理解しておきたいのが、!=です。

!=は「等しくない」を表す比較演算子です。

C#
if (x != y)
{
Console.WriteLine("xとyは等しくありません");
}

一方、notはパターンを否定するキーワードです。

C#
if (value is not null)
{
Console.WriteLine("nullではありません");
}

見た目は似ていませんが、どちらも「〜ではない」という意味を持つため、初心者が混同しやすいポイントです。

5-1. 「!=」は左右の値が等しくないことを比較する演算子

!=は、左側と右側の値が等しくないかを判定します。

C#
int a = 10;
int b = 20;

if (a != b)
{
Console.WriteLine("aとbは異なります");
}

文字列にも使えます。

C#
string status = "Error";

if (status != "OK")
{
Console.WriteLine("ステータスはOKではありません");
}

このように、!=は値の比較に使います。

==が「等しい」を表すのに対して、!=は「等しくない」を表します。

C#
x == y // xとyが等しい
x != y // xとyが等しくない

5-2. 「not」は条件やパターンを否定する考え方

notは、値同士を比較する演算子ではありません。

C#では、パターンマッチングの中で使います。

C#
if (value is not string)
{
Console.WriteLine("文字列ではありません");
}

これは、valuestring型というパターンに一致しないことを表します。

notは、次のようにパターンを否定していると考えると理解しやすいです。

C#
value is not null

これは「valueはnullパターンではない」。

C#
value is not string

これは「valueはstring型パターンではない」。

C#
score is not (>= 0 and <= 100)

これは「scoreは0以上100以下のパターンではない」。

5-3. 「x != null」と「x is not null」の違い

nullチェックでは、次の2つがよく比較されます。

C#
if (x != null)
{
}
C#
if (x is not null)
{
}

どちらも「xがnullではない場合」という意味で使われます。

ただし、考え方が少し違います。

x != nullは、xとnullが等しくないかを比較しています。

x is not nullは、xがnullパターンに一致しないことを判定しています。

一般的なコードでは、どちらも同じように使われることが多いです。

ただし、is not nullはパターンマッチングの構文なので、nullチェックの意図がより明確に見える場合があります。

C#
if (user is not null)
{
Console.WriteLine(user.Name);
}

このように書くと、「userがnullでないときだけ処理する」と読みやすくなります。

5-4. 「!(x == y)」と「x != y」の違い

次の2つは、多くの場合、同じ意味になります。

C#
if (!(x == y))
{
Console.WriteLine("等しくありません");
}
C#
if (x != y)
{
Console.WriteLine("等しくありません");
}

ただし、読みやすさではx != yのほうが自然です。

!(x == y)は、「xとyが等しい、ではない」と読む必要があります。

一方、x != yは「xとyは等しくない」とそのまま読めます。

そのため、値が等しくないことを表したい場合は、基本的に!=を使うのがおすすめです。

C#
if (password != confirmPassword)
{
Console.WriteLine("パスワードが一致しません");
}

このほうが、否定の意図が明確です。

5-5. どちらを使うと読みやすいか

読みやすさを基準にすると、次のように使い分けるとよいです。

値が等しくないことを表すなら!=を使います。

C#
if (count != 0)
{
Console.WriteLine("件数があります");
}

nullではないことを表すならis not nullを使うと読みやすいです。

C#
if (customer is not null)
{
Console.WriteLine(customer.Name);
}

bool条件を反転するなら!を使います。

C#
if (!isRunning)
{
Console.WriteLine("実行中ではありません");
}

無理にすべてを!で書こうとすると、かえって読みにくくなります。

C#
if (!(count == 0))
{
Console.WriteLine("件数があります");
}

この場合は、次のように書いたほうがわかりやすいです。

C#
if (count != 0)
{
Console.WriteLine("件数があります");
}

6. C#のnot演算子の具体的な使い方

ここからは、C#のnot演算子に関連する具体的な使い方を見ていきます。

実務でもよく出てくるパターンを中心に紹介します。

6-1. if文で条件を反転する

bool条件を反転する基本形です。

C#
bool isAvailable = false;

if (!isAvailable)
{
Console.WriteLine("利用できません");
}

isAvailableは「利用できる」という意味です。

!isAvailableは「利用できない」という意味になります。

次のように、条件式全体を反転することもできます。

C#
int age = 16;

if (!(age >= 18))
{
Console.WriteLine("18歳未満です");
}

ただし、この場合は次のように書いたほうが読みやすいです。

C#
if (age < 18)
{
Console.WriteLine("18歳未満です");
}

否定を使う前に、より自然な条件式で書けないか考えることが大切です。

6-2. bool変数を否定する

bool変数に!を付ける例です。

C#
bool hasError = true;

if (!hasError)
{
Console.WriteLine("エラーはありません");
}
else
{
Console.WriteLine("エラーがあります");
}

!hasErrorは「エラーがない」という意味です。

ただし、変数名が否定形の場合は注意が必要です。

C#
bool isNotFound = true;

if (!isNotFound)
{
Console.WriteLine("見つかりました");
}

このコードは読みにくいです。

isNotFound!が付いているため、「見つからない、ではない」という二重否定になっています。

できれば、肯定形の変数名にすると読みやすくなります。

C#
bool isFound = false;

if (!isFound)
{
Console.WriteLine("見つかりませんでした");
}

6-3. メソッドの戻り値を否定する

boolを返すメソッドに対して!を使うこともよくあります。

C#
static bool IsValidEmail(string email)
{
return email.Contains("@");
}

string email = "sample.example.com";

if (!IsValidEmail(email))
{
Console.WriteLine("メールアドレスが正しくありません");
}

IsValidEmail(email)は、メールアドレスが正しければtrueを返します。

そこに!を付けることで、「正しくない場合」を表せます。

ファイルの存在確認でもよく使います。

C#
string path = "data.txt";

if (!File.Exists(path))
{
Console.WriteLine("ファイルが存在しません");
}

このように、!メソッド名()という形はC#で非常によく使われます。

6-4. nullではない場合だけ処理する

nullではない場合だけ処理したいときは、is not nullが便利です。

C#
string? message = "Hello";

if (message is not null)
{
Console.WriteLine(message.Length);
}

messageがnullではない場合だけ、Lengthにアクセスしています。

nullの可能性がある値に対して、いきなりプロパティやメソッドを呼ぶとエラーの原因になります。

C#
string? message = null;

// 実行時エラーの原因になる
Console.WriteLine(message.Length);

そのため、nullチェックをしてから使うことが重要です。

C#
if (message is not null)
{
Console.WriteLine(message.Length);
}

また、次のように!= nullで書くこともできます。

C#
if (message != null)
{
Console.WriteLine(message.Length);
}

チームの方針やコードの雰囲気に合わせて選ぶとよいでしょう。

6-5. 特定の型ではない場合に処理する

is notは、特定の型ではない場合の処理にも使えます。

C#
object value = 123;

if (value is not string)
{
Console.WriteLine("文字列ではありません");
}

もう少し実用的な例を見てみましょう。

C#
static void PrintLength(object value)
{
if (value is not string text)
{
Console.WriteLine("文字列ではないため、長さを表示できません");
return;
}

Console.WriteLine(text.Length);
}

PrintLength("Hello");
PrintLength(123);

このコードでは、valueがstringではない場合に早めにreturnしています。

valueがstringの場合だけ、text.Lengthを使えます。

このような書き方は、ガード節と呼ばれることがあります。

C#
if (value is not string text)
{
return;
}

先に「処理できない条件」を除外することで、その後のコードが読みやすくなります。

6-6. 複数条件と組み合わせて使う

!は、複数条件と組み合わせて使うこともあります。

C#
bool isAdmin = false;
bool isOwner = false;

if (!isAdmin && !isOwner)
{
Console.WriteLine("管理者でも所有者でもありません");
}

&&は「かつ」を表します。

この条件は、「管理者ではない、かつ、所有者でもない」という意味です。

また、||と組み合わせることもあります。

C#
bool hasName = false;
bool hasEmail = true;

if (!hasName || !hasEmail)
{
Console.WriteLine("名前またはメールアドレスが不足しています");
}

||は「または」を表します。

この条件は、「名前がない、または、メールアドレスがない」という意味です。

ただし、否定と複数条件を組み合わせると読みにくくなりやすいです。

必要に応じて、bool変数に分けると読みやすくなります。

C#
bool missingName = !hasName;
bool missingEmail = !hasEmail;

if (missingName || missingEmail)
{
Console.WriteLine("入力が不足しています");
}

7. C#のnot演算子でよくあるミス

C#のnot演算子や否定条件では、初心者がつまずきやすいポイントがいくつかあります。

ここでは、よくあるミスを具体例とともに紹介します。

7-1. 「not」と書けばどこでも使えると誤解する

C#では、notをどこでも使えるわけではありません。

たとえば、次のコードは基本的に誤りです。

C#
bool isValid = false;

// エラー
if (not isValid)
{
}

C#でbool値を否定したい場合は、!を使います。

C#
if (!isValid)
{
Console.WriteLine("有効ではありません");
}

notは、主にパターンマッチングの中で使います。

C#
if (value is not null)
{
Console.WriteLine("nullではありません");
}

「boolの否定は!」「パターンの否定はnot」と覚えるとよいです。

7-2. 「!」を付ける位置を間違える

!は、否定したいbool式の前に付けます。

C#
if (!isActive)
{
}

メソッド呼び出しを否定する場合も、メソッド呼び出し全体の前に付けます。

C#
if (!IsActive())
{
}

複雑な条件を否定する場合は、括弧を使います。

C#
if (!(age >= 18 && hasPermission))
{
Console.WriteLine("条件を満たしていません");
}

括弧を付けないと、意図しない意味になることがあります。

C#
if (!age >= 18)
{
// これはエラー
}

ageはint型なので、!ageとは書けません。

!はboolに対して使うため、比較式全体を括弧で囲む必要があります。

C#
if (!(age >= 18))
{
Console.WriteLine("18歳未満です");
}

ただし、この場合は次のほうが自然です。

C#
if (age < 18)
{
Console.WriteLine("18歳未満です");
}

7-3. 「!」「!=」「is not」を混同する

次の3つは、それぞれ使う場面が異なります。

C#
!isValid

これはbool値の否定です。

C#
x != y

これは値が等しくないことの比較です。

C#
x is not null

これはパターンに一致しないことの判定です。

たとえば、次のように書くとエラーになります。

C#
string? name = "Taro";

// エラー
if (!name)
{
}

nameはstring型であり、bool型ではありません。

そのため、!nameとは書けません。

nullではないことを確認したいなら、次のように書きます。

C#
if (name is not null)
{
Console.WriteLine(name);
}

または、

C#
if (name != null)
{
Console.WriteLine(name);
}

7-4. 否定条件を重ねすぎて読みにくくなる

否定条件を重ねると、コードが読みにくくなります。

C#
if (!isNotEnabled)
{
Console.WriteLine("有効です");
}

これは「有効ではない、ではない」という意味になり、直感的に読みにくいです。

変数名を肯定形にするとわかりやすくなります。

C#
bool isEnabled = true;

if (isEnabled)
{
Console.WriteLine("有効です");
}

複雑な条件でも同じです。

C#
if (!(age < 18 || !hasPermission))
{
Console.WriteLine("利用できます");
}

このような条件は、読み解くのに時間がかかります。

次のように分けると読みやすくなります。

C#
bool isAdult = age >= 18;
bool canUse = isAdult && hasPermission;

if (canUse)
{
Console.WriteLine("利用できます");
}

7-5. null許容参照型とnullチェックを混同する

C#には、null許容参照型という仕組みがあります。

C#
string? name = null;

string?は、「nullになる可能性があるstring」を表します。

ただし、?を付けたからといって、nullチェックが不要になるわけではありません。

C#
string? name = null;

// nameがnullの可能性がある
if (name is not null)
{
Console.WriteLine(name.Length);
}

string?は、コンパイラに「この変数はnullかもしれない」と伝えるためのものです。

実際に安全に使うためには、is not nullなどでnullチェックを行う必要があります。

次のように、nullチェック後であれば安全に扱いやすくなります。

C#
if (name is not null)
{
Console.WriteLine(name.Length);
}

7-6. 演算子の優先順位を理解せずに使う

!は優先順位が高い演算子です。

そのため、複雑な条件では括弧を使って意図を明確にすることが大切です。

たとえば、次のコードを見てください。

C#
bool isAdmin = false;
bool isOwner = true;

if (!isAdmin && isOwner)
{
Console.WriteLine("管理者ではないが、所有者です");
}

この場合、!isAdminにだけかかります。

つまり、次のような意味です。

C#
if ((!isAdmin) && isOwner)
{
}

条件全体を否定したい場合は、括弧が必要です。

C#
if (!(isAdmin && isOwner))
{
Console.WriteLine("管理者かつ所有者、ではありません");
}

否定する範囲を間違えると、プログラムの動作も変わります。

複数条件を否定するときは、括弧を使って読みやすく書きましょう。

8. not演算子を読みやすく書くコツ

否定条件は便利ですが、使い方によっては読みにくいコードになりやすいです。

ここでは、C#でnot演算子や否定条件を読みやすく書くためのコツを紹介します。

8-1. 否定条件はできるだけシンプルにする

否定条件は、できるだけ短くシンプルにしましょう。

C#
if (!isValid)
{
Console.WriteLine("無効です");
}

この程度であれば、すぐに意味がわかります。

一方で、次のように複雑な条件を否定すると読みにくくなります。

C#
if (!(age >= 18 && hasPermission && isActive))
{
Console.WriteLine("利用できません");
}

この場合、どの条件が原因で利用できないのかがわかりにくいです。

次のように分けると読みやすくなります。

C#
bool canUse = age >= 18 && hasPermission && isActive;

if (!canUse)
{
Console.WriteLine("利用できません");
}

8-2. 否定より肯定で書けないか考える

否定条件は、肯定条件に変えたほうが読みやすくなることがあります。

たとえば、次のコードです。

C#
if (!(age >= 18))
{
Console.WriteLine("未成年です");
}

この場合、次のように書いたほうが自然です。

C#
if (age < 18)
{
Console.WriteLine("未成年です");
}

また、次のコードも考えてみましょう。

C#
if (!isNotAvailable)
{
Console.WriteLine("利用可能です");
}

これは二重否定で読みにくいです。

変数名を肯定形に変えると、わかりやすくなります。

C#
if (isAvailable)
{
Console.WriteLine("利用可能です");
}

否定を書く前に、「肯定形で書けないか」を考える習慣をつけると、コードの可読性が上がります。

8-3. 変数名やメソッド名で意味を補う

!は短く書ける反面、それだけでは意味が伝わりにくいことがあります。

そのため、変数名やメソッド名をわかりやすくすることが重要です。

C#
if (!flag)
{
}

このコードは、flagが何を表しているのかわかりません。

次のように書くと、意味が明確になります。

C#
if (!isLoggedIn)
{
Console.WriteLine("ログインしてください");
}

メソッド名も同じです。

C#
if (!Check(user))
{
}

これでは、何をチェックしているのかわかりません。

次のようにすると、否定しても意味が伝わりやすくなります。

C#
if (!HasPermission(user))
{
Console.WriteLine("権限がありません");
}

否定条件を読みやすくするには、!そのものよりも、名前の付け方が重要です。

8-4. 複雑な条件は一度bool変数に分ける

複雑な条件をそのままif文に書くと、読みにくくなります。

C#
if (!string.IsNullOrEmpty(name) && age >= 18 && status != "Blocked")
{
Console.WriteLine("登録できます");
}

この程度ならまだ読めますが、条件が増えると理解しにくくなります。

次のようにbool変数に分けると、読みやすくなります。

C#
bool hasName = !string.IsNullOrEmpty(name);
bool isAdult = age >= 18;
bool isNotBlocked = status != "Blocked";

if (hasName && isAdult && isNotBlocked)
{
Console.WriteLine("登録できます");
}

さらに、最終的な条件名を付けてもよいです。

C#
bool canRegister = hasName && isAdult && isNotBlocked;

if (canRegister)
{
Console.WriteLine("登録できます");
}

条件に名前を付けることで、コードが文章のように読めるようになります。

8-5. チーム開発で読みやすい書き方を選ぶ

C#では、同じ意味を複数の書き方で表せることがあります。

たとえば、nullチェックです。

C#
if (user != null)
{
}
C#
if (user is not null)
{
}

どちらも使われます。

大切なのは、チーム内で読みやすい書き方を選ぶことです。

既存のコードでis not nullが多く使われているなら、それに合わせると統一感が出ます。

逆に、既存コードで!= nullが多いなら、無理にis not nullへ変えなくてもよい場合があります。

コードは自分だけでなく、他の人も読みます。

「正しく動くか」だけでなく、「読んだ人がすぐ理解できるか」を意識しましょう。

9. 初心者向け:not演算子の練習問題

ここでは、C#のnot演算子や否定条件を理解するための練習問題を紹介します。

コードを読むだけでなく、自分で書いて試してみると理解が深まります。

9-1. true・falseを反転する練習

次のコードの出力を考えてみましょう。

C#
bool a = true;
bool b = false;

Console.WriteLine(!a);
Console.WriteLine(!b);

答えは次のようになります。

C#
False
True

!truefalseになります。

!falsetrueになります。

次のように、変数に代入して確認することもできます。

C#
bool isOpen = true;
bool isClosed = !isOpen;

Console.WriteLine(isClosed); // False

isOpenがtrueなので、!isOpenはfalseです。

9-2. if文の条件を否定する練習

次のコードを見てください。

C#
bool isLoggedIn = false;

if (!isLoggedIn)
{
Console.WriteLine("ログインが必要です");
}

出力は次のようになります。

C#
ログインが必要です

isLoggedInはfalseです。

!isLoggedInはtrueになるため、if文の中が実行されます。

次の練習です。

C#
bool hasTicket = true;

if (!hasTicket)
{
Console.WriteLine("チケットがありません");
}
else
{
Console.WriteLine("入場できます");
}

この場合、出力は次のようになります。

C#
入場できます

hasTicketがtrueなので、!hasTicketはfalseです。

そのため、else側が実行されます。

9-3. nullチェックを「is not null」で書く練習

次のコードを見てください。

C#
string? name = "Hanako";

if (name is not null)
{
Console.WriteLine(name.Length);
}

nameはnullではないため、文字数が出力されます。

C#
6

次のように、nullの場合も試してみましょう。

C#
string? name = null;

if (name is not null)
{
Console.WriteLine(name.Length);
}
else
{
Console.WriteLine("nameはnullです");
}

出力は次のようになります。

C#
nameはnullです

is not nullは、「nullではない場合だけ処理する」ためによく使います。

9-4. 「!=」と「is not」を使い分ける練習

次の2つのコードを比べてみましょう。

C#
int x = 10;
int y = 20;

if (x != y)
{
Console.WriteLine("xとyは等しくありません");
}

これは、xとyの値が等しくないことを比較しています。

次のコードは、nullではないことを判定しています。

C#
string? text = "Hello";

if (text is not null)
{
Console.WriteLine(text);
}

値同士を比較するなら!=です。

C#
if (status != "OK")
{
Console.WriteLine("OKではありません");
}

nullではないことをパターンとして判定するならis not nullです。

C#
if (user is not null)
{
Console.WriteLine("ユーザーが存在します");
}

9-5. よくある間違いを修正する練習

次のコードは間違いです。

C#
bool isValid = false;

if (not isValid)
{
Console.WriteLine("無効です");
}

C#では、bool値を否定するためにnotを単独では使いません。

正しくは次のように書きます。

C#
if (!isValid)
{
Console.WriteLine("無効です");
}

次のコードも間違いです。

C#
string? name = "Taro";

if (!name)
{
Console.WriteLine("名前がありません");
}

nameはboolではないため、!nameとは書けません。

nullチェックをしたいなら、次のように書きます。

C#
if (name is null)
{
Console.WriteLine("名前がありません");
}

nullではない場合を判定したいなら、次のように書きます。

C#
if (name is not null)
{
Console.WriteLine(name);
}

10. C#のnot演算子に関するよくある質問

ここでは、C#のnot演算子について初心者が疑問に思いやすい内容をQ&A形式でまとめます。

10-1. C#でnotと書くことはできますか?

C#でnotと書くことはできます。

ただし、Pythonのようにbool値を否定するために単独で使うわけではありません。

C#のnotは、主にパターンマッチングで使います。

C#
if (value is not null)
{
Console.WriteLine("nullではありません");
}

次のような書き方はできません。

C#
if (not isValid)
{
}

bool値を否定したい場合は、!を使います。

C#
if (!isValid)
{
Console.WriteLine("有効ではありません");
}

10-2. 「!」はnot演算子ですか?

!は、C#の論理否定演算子です。

一般的には「not演算子」と説明されることもあります。

bool値を反転するために使います。

C#
bool isEnabled = false;

Console.WriteLine(!isEnabled); // True

!は、trueをfalseに、falseをtrueにします。

C#
!true  // false
!false // true

C#で条件を否定したいときに最も基本となる演算子です。

10-3. 「is not null」と「!= null」はどちらがよいですか?

どちらもnullではないことを判定するために使えます。

C#
if (value != null)
{
}
C#
if (value is not null)
{
}

最近のC#では、is not nullを使うコードもよく見かけます。

is not nullは「nullパターンではない」と読めるため、意図が明確です。

一方、!= nullは昔からある比較演算子による書き方で、多くのC#コードで使われています。

初心者には、次のような使い分けがおすすめです。

nullチェックを自然に読みたいなら、is not nullを使います。

C#
if (user is not null)
{
Console.WriteLine(user.Name);
}

値の比較として書きたいなら、!= nullを使っても問題ありません。

C#
if (user != null)
{
Console.WriteLine(user.Name);
}

10-4. 「not」はC#のどのバージョンから使えますか?

パターンマッチングで使うnotパターンは、C# 9.0から使えるようになりました。

そのため、古いC#バージョンを使っている環境では、is not nullなどの構文が使えない場合があります。

古い環境では、次のように!= nullを使います。

C#
if (value != null)
{
Console.WriteLine(value);
}

C# 9.0以降を使える環境であれば、次のように書けます。

C#
if (value is not null)
{
Console.WriteLine(value);
}

使用しているC#のバージョンやプロジェクト設定によって使える構文が変わるため、エラーが出る場合は言語バージョンを確認しましょう。

10-5. 「!」が2つ付く「!!」はC#で使いますか?

C#で!!は、JavaScriptのように値をboolに変換する目的では一般的に使いません。

たとえば、JavaScriptでは次のような書き方があります。

JavaScript
!!value

しかし、C#ではboolではない値に!を付けることはできません。

C#
string text = "Hello";

// エラー
bool result = !!text;

C#の!はbool値に対する論理否定です。

bool変数に対して!!を書くこと自体は可能です。

C#
bool isActive = true;

Console.WriteLine(!!isActive); // True

しかし、これはisActiveと同じ意味になるため、通常は書きません。

C#
Console.WriteLine(isActive); // True

C#では、!!を使う必要はほとんどありません。

10-6. 否定条件が読みにくいときはどうすればよいですか?

否定条件が読みにくいときは、次の3つを試してみましょう。

まず、肯定条件で書けないか考えます。

C#
if (!(age >= 18))
{
}

これは次のほうが読みやすいです。

C#
if (age < 18)
{
}

次に、条件をbool変数に分けます。

C#
bool canUse = age >= 18 && hasPermission;

if (!canUse)
{
Console.WriteLine("利用できません");
}

最後に、変数名やメソッド名を見直します。

C#
if (!isNotReady)
{
}

これは読みにくいので、肯定形に変えます。

C#
if (isReady)
{
}

否定条件は便利ですが、読みやすさを優先することが大切です。

まとめ

C#で「not演算子」と聞くと、notというキーワードを思い浮かべるかもしれません。

しかし、C#でbool値を否定する基本の演算子は!です。

C#
if (!isValid)
{
Console.WriteLine("有効ではありません");
}

!は、trueをfalseに、falseをtrueに反転する論理否定演算子です。

bool変数や、boolを返すメソッドに対して使います。

C#
if (!File.Exists(path))
{
Console.WriteLine("ファイルが存在しません");
}

一方、C#のnotは、主にパターンマッチングで使います。

代表的な書き方はis not nullです。

C#
if (value is not null)
{
Console.WriteLine("nullではありません");
}

is notは、指定したパターンに一致しないことを表します。

型チェックにも使えます。

C#
if (value is not string)
{
Console.WriteLine("文字列ではありません");
}

また、!=は左右の値が等しくないことを比較する演算子です。

C#
if (x != y)
{
Console.WriteLine("xとyは等しくありません");
}

C#の否定を整理すると、次のようになります。

bool値を否定するなら!

C#
!isActive

パターンに一致しないことを表すならis not

C#
value is not null

値が等しくないことを比較するなら!=

C#
x != y

初心者は、まずこの3つの違いを押さえましょう。

否定条件は便利ですが、使いすぎるとコードが読みにくくなります。

複雑な条件はbool変数に分けたり、肯定形で書けないか考えたりすると、読みやすいC#コードになります。