こんなメソッドを書いてみよう §
以下のようなメソッドを書いてみよう。
- bool型の引数を2つ取る
- 一つ目は有効無効の指定 isEnabled
- 二つ目は値 flag
- isEnabledがtrueならflagの値を反転してConsole.WriteLineで出力する
普通に書くと §
普通にifを使って書くと、サンプルソースのsub1のようになります。
しかし、機能に比してちょっと長いですね。論理反転の演算子などを使うともっと短くできそうです。
XOR(排他的論理和)で書くと §
これはサンプルソースのsub2のように書いても等価です。
なぜでしょうか。
XOR(排他的論理和)は、【どちらか1つだけtrueなら結果はtrue】になる演算子です。
しかし、これを【第1の値がtrueなら第2の値を反転させる。falseなら反転させない演算子】と読み替えると、今回のお題にピッタリだと分かります。
実はifも反転演算子も必要ありません。
論理の不思議ですね。
罠の数々 §
- XORは便利だが、使える場面は多くない。過剰な期待はしない方が良い
- むしろ、XORの出番を作るためにあえてXORで便利に処理できるようにデータ構造を定義しても良い (それでコード全体がコンパクトになるなら必ずしも悪いことではない)
- しかし、XORを多用すると【分かりにくいソースだ】と怒られるリスクもある
参考リンク §
メンバー アクセス演算子と式 (C# リファレンス)
ブール論理演算子 (C# リファレンス)
Visual Studioで^にキャレットを置いてF1を押すと【メンバー アクセス演算子と式】のページが開いてしまうが、ここで使っているのはその【^ (末尾からのインデックス)】ではない。実際はブール論理演算子の【 ^ (論理排他的 OR) 演算子】の方である。間違えないように注意しよう。^は文脈によって意味が変わるのである。上記のリンクをクリックして違いを確認しておこう。
リポジトリ §
https://github.com/autumn009/cshowto
xor §
using System;
class Program
{
private static void sub1(bool isEnabled, bool flag)
{
if( isEnabled)
{
if (flag) flag = false; else flag = true;
}
Console.WriteLine(flag);
}
private static void sub2(bool isEnabled, bool flag)
{
Console.WriteLine(isEnabled ^ flag);
}
static void Main()
{
sub1(false, true);
sub1(true, true);
sub2(false, true);
sub2(true, true);
}
}
実行結果
True
False
True
False