C#言語の演算子 誤用しやすいのと新しいのと

基本文法
C#言語に定義されている多くの演算子は、その系譜であるDelphiやC/C++といった言語と同じようなものです。
ここでは、あまり見かけないものや最近追加されたものを簡単に紹介します。詳細は以下の公式で確認下さい。

公式ページはこちら C#演算子と式

等値演算子

== で等値であるかを確認します。
= は右辺値の演算結果を左辺値へ代入するために使います。

間違いやすくバグの元でしたが誤用の疑いあるところではVisualStudioが警告をしてくれます。

・参照型では同じオブジェクトへの参照かを確認します。
・参照型ですが文字列型(string)は同じ文字列かを確認します。
・値型では全てのメンバが同じ値かを確認します。
 
 ※等値比較については別途記載予定

条件演算子(三項条件演算子)とref条件式

条件演算子

?: でブール式(true or falseを返す式)の成否によりどちらかを返すもの。
(これは比較的多くの言語でみかけます)
         // ライフがダメージより少なければ0になる
         public int SubstractA(int life,int damage)
        {
            if(life < damage)
            {
                return 0;
            }
            else
            {
                return life - damage;
            }
        }

        // 三項演算子で書けば一行でOK
        public int SubstractB(int life, int damage) => life < damage ? 0 : life - damage;
            

ref 条件式

C# 7.2 以降で追加されました。
var smallArray = new int[] { 1, 2, 3, 4, 5 };
var largeArray = new int[] { 10, 20, 30, 40, 50 };

int index = 7;
ref int refValue = ref ((index < 5) ? ref smallArray[index] : ref largeArray[index - 5]);
refValue = 0;

// 結果はlargeArrayが10, 20, 0, 40, 50となります。

null条件演算子とnull合体演算子とnull合体代入演算子

null条件演算子

C# 6 以降で追加されました。
?. で左辺がNULLではない場合に右辺が実行されます
// oがNULLではない場合はToStringメソッドの結果が、NULLの場合はNULLが
// Writeメソッドの引数として引き渡されます。
public void WriteLog(object o) => Logger.Write(o?.ToString());

null合体演算子

C# 2 以降で追加されました。(これはずいぶんと前から使えたんですね)
?? で左辺がNULLでないなら左辺が、NULLの場合は右辺が返されます
デフォルト値の設定などで使います。
public void WriteLog(string s) => Logger.Write(s ?? "NULL');

null合体代入演算子

C#8.0以降で追加されました。
??= で左辺がNULLの場合に右辺の値を代入します。
public void WriteLog(string s)
{
    s ??="NULL";
    Logger.Write(s);
}

null 免除演算子

C#8.0以降で追加されました。
参照型もデフォでNULLとならないよう(構造体のよう)にすることができます。
このようなNULL許容注釈コンテキスト(nullable annotation context)内において
参照型の式がNULLではないことを示します。
#nullable enable

            // GetDataは引数の名前に相当するデータクラスを取得する想定
            Data? data = GetData("AAA");

            if(data != null)
            {
                // dataはNULLの可能性があるとの警告がでる
                // Console.WriteLine(data.Value);

                // !をつければOK
                Console.WriteLine(data!.Value);
            }


#nullable disable

末尾からのインデックス演算子(Index from end operator)と範囲演算子(Range operator)

C#8.0以降で追加されました。
^ で後ろからのインデックスとなります .. で範囲をとります

            int[] array = new[] { 0, 1, 2, 3, 4, 5, 6 };

            int ret1   = array[2];    // 2
            int ret2   = array[^2];   // 5
            int[] ret3 = array[3..5]; // 3, 4