Theme
SD MILIEU

2018-4-8

独習C#メモ

C#に関して、自分が知ってる言語には無かった点や罠になりそうな点をまとめておく。

ドキュメンテーションコメント

以下のように/// <summary>でドキュメンテーションコメントが記述出来る。

ドキュメンテーションコメントの内容は、インテリセンスの際に要約として表示してくれる。

(インテリセンスへは VisualStudio を開き直さないと反映されなかった。)

using System;

namespace csharp_test
{
    class Program
    {
        /// <summary>
        /// 「Hello World」と出力
        /// </summary>
        static void Hello()
        {
            Console.WriteLine("Hello World!");
        }

        static void Main(string[] args)
        {
            Program.Hello();
        }
    }
}

var による型推論

C#は静的型付け言語なので、

int counter = 0;

というように、変数宣言の際に型を指定子なければならない。

ただ、C#3 からvarによる型推論が導入され、

var counter = 0;

と宣言すると、右辺(この場合0)を見て型を自動的に設定してくれる。

注意なのは、あくまで自動的な型付けをしてくれるだけであって、動的型付けになったわけではない。

なので、以下のソースはコンパイルエラーとなる。

var counter = 0;
var userInput = "hoge";

// int型にstring型を代入しようとしてるのでエラー
counter = userInput;

また、フィールドに対しては var を使用できないことも注意。

文字列への変数展開

ES におけるテンプレートリテラルのような仕様が C#でも存在している。(C#6 から使える)

$"..."のように、文字列リテラルの前の$を指定すると、変数・式を{}で囲むことで展開してくれる。

var name = "山田";
var text = $"彼の名前は{name}です。";

Console.WriteLine(text);

整数型から浮動小数点への変換の際の桁落ち

float型は仮数部が 23 ビットのため、16777216(2^24)以上の整数を変換しようとすると桁落ちが発生してしまう

int i = 16777216;
float f = i;
Console.WriteLine(f); // => 1.677722E+07

null 条件演算子・null 合体演算子

nullな変数のメソッドにアクセスしようとすると、当然例外が発生してしまう。

そのため null チェックが必要となるわけだが、変数が null でない時だけメソッドにアクセスする「null 条件演算子」と、null でなければ後ろに続く式を返す「null 合体演算子」が便利。

null 条件演算子は

string text = null;

string outText = text?.Trim(); // outTextにはnullが入る

のように、変数が null の際にはメソッドへのアクセスをスルーして null と評価してくれる。

null 合体演算子は

string text = null;

string outText = text ?? "text is null"; // "text is null"がoutTextに入る

のように、A ?? Bのように記述し、A が null の際には B と評価される。

この2つを利用すると

string text = null;
string outText = null;

if (text != null)
{
    outText = text.Trim();
} else {
    outText = "text is null";
}

Console.WriteLine(outText);

このようなコードが

string text = null;

string outText = text?.Trim() ?? "text is null";

Console.WriteLine(outText);

のようにすっきりかける。

null 許容型

値型は null を通常扱えないが、int?のように?を付けることで null を扱える「null 許容型」として宣言できる。

int? num = null; // エラーにならない

多次元配列・ジャグ配列

多次元配列は行・列がそれぞれツラが揃っている配列で、ジャグ配列は不揃いな配列のこと。

多次元配列の宣言

int[,] data = new int[3, 3];

int[,] data = {
    {1, 2, 3},
    {1, 2, 3},
    {1, 2, 3},
};

int[,] data = {
    {1, 2, 3},
    {1, 2, 3},
    {1}, // ツラが揃ってないのでエラー
};

ジャグ配列の宣言

int[][] data = new int[3][];
data[0] = new int[3];
data[1] = new int[2];
data[2] = new int[5];

整数同士の除算

整数同士の除算は、自動的に整数化されてしまう。

double result = 3 / 4;
Console.WriteLine(result); // => 0

なので、少数が欲しい時は明示的にdなりfなりをつけて少数が返ってくるようにすること。

double result = 3d / 4;
Console.WriteLine(result); // => 0.75

参照型の比較

参照型の比較は、参照先が同じか否かで判断される。

int[] data01 = { 1 };
int[] data02 = { 1 };

Console.WriteLine(data01 == data02); // => false

例外として、文字列は中身が同じか否かで判断される。

string text01 = "hoge";
string text02 = "hoge";

Console.WriteLine(text01 == text02); // => true

nameof 演算子

nameof演算子を使用することで、識別子を文字列として取得することが出来る。

var counter = 10;

Console.WriteLine(nameof(counter) + " is " + counter); // => counter is 10

これの何が嬉しいかというと、VisualStudio の「名前の変更」機能の対象になってくれるのが嬉しいみたい。

foreach

foreach (value in Collection)という書き方で foreach が利用できる。

string[] magius = {
    "ドグ",
    "マグ",
    "ラグ",
};

foreach (var name in magius)
{
    Console.WriteLine(name);
}