【C#】Nullable<T>型をキャストする方法

「Nullable<T>型(null 許容型)って、どうやってnull非許容型にするの?」
「Nullableからのキャストって、簡単にできないよね?」

こんなことを悩んでいませんか?
こういった疑問に答えます。

今日は「Nullable<T>型(null 許容型)を、null非許容型にキャストする方法」について紹介します。

目次

Nullable<T>型とは?

Nullable<T>型

値型の型名の後ろに?を付けて、元の型の値もnullの値も取れる型にするものです。

int型を例にすると、こんな書き方になります。

int? x = 11;
int? y = null;
int z = null; //←『null非許容型』これはエラーになる

ときどき『セットした値の0』と、『nullと同じ意味の0』みたいなものが混じってしまっていたり、-999みたいな『あり得ない値』に特別な意味を持たせるようなコーディングをしないために活用する方法です。

ですが、このNullable<T>型には、null非許容型のメソッド・プロパティの全てサポートしてるわけではないという欠点があります。

次で、DateTime?型を例にして説明します。

【C#】Nullable<T>型の問題点

DateTime型のプロパティやメソッドを使いたいとき、DateTime?型のままだと使えないものがあります。

例えば、以下の例のようなものです。

public void Main()
{
    // DateTime
    DateTime date = DateTime.Now;

    Console.WriteLine($"date  : {date.ToString()}");

    var date1 = date.Date;
    var date2 = date.AddDays(1);

    Console.WriteLine($"date1 : {date1.ToString()}");
    Console.WriteLine($"date2 : {date2.ToString()}");
}

// 【実行結果】
date  : 2019/12/16 23:20:00

date1 : 2019/12/16  0:00:00
date2 : 2019/12/17 23:20:00

ソースを見てください。date.Date;で日付だけの取り出し、date.AddDays(1);で日数を足したり、よく使いますよね。

DateTime?型で同じように使ってみるとどうでしょう。

public void Main()
{
    // DateTime null許容型
    DateTime? nullableDate = DateTime.Now;

    //var date3 = nullableDate.Date;       // null許容型なので構文エラーになる
    //var date4 = nullableDate.AddDays(1); // null許容型なので構文エラーになる
}

構文エラーになります。

DateTime?型で変数.Date変数.AddDays(1)はそのままでは使えないんです。

ではどうしたらいいのでしょうか?

この次で説明していきます。

【C#】Nullable<T>型をキャストする方法

答えは簡単です。

null非許容型にキャストすれば、使うことができます。

DateTime型のプロパティやメソッドなので、当たり前と言えば当たり前です。

それでは、Nullable<T>型(null 許容型)を、null非許容型にキャストする方法です。

public void Main()
{
    // DateTime null許容型
    DateTime? nullableDate = DateTime.Now;

    Console.WriteLine($"nullableDate : {nullableDate.ToString()}");

    // DateTime?→DateTimeに変換する方法① 
    // ”変数.Value”での変換
    var date5 = nullableDate.Value.Date;       // 構文エラーにならない
    var date6 = nullableDate.Value.AddDays(1); // 構文エラーにならない

    Console.WriteLine($"date5        : {date5.ToString()}");
    Console.WriteLine($"date6        : {date6.ToString()}");


    // DateTime?→DateTimeに変換する方法②
    // ”((DateTime)変数)”での変換
    var date7 = ((DateTime)nullableDate).Date;       // 構文エラーにならない
    var date8 = ((DateTime)nullableDate).AddDays(1); // 構文エラーにならない

    Console.WriteLine($"date7        : {date7.ToString()}");
    Console.WriteLine($"date8        : {date8.ToString()}");
}

// 【実行結果】
nullableDate : 2019/12/16 23:24:45

date5        : 2019/12/16  0:00:00
date6        : 2019/12/17 23:24:45

date7        : 2019/12/16  0:00:00
date8        : 2019/12/17 23:24:45

ソースを見てください。変数.Value((DateTime)変数)これだけで、DateTime?型から、DateTime型に変換できます。

どういうわけか、意外とネットで検索しても出てこないみたいです。

まとめ

ときどきnew DateTime();してDateTimeを作り直しているコードを見かけることがあります。

もっと簡単に変換できるので、ぜひこのやり方を覚えておいてください。

綺麗なコードを書くコツを知りたい方は「【C#】初心者が綺麗なコードを書くコツ Tips」のページをどうぞ。

他にもDateTime 値の日付部分のみ取得する方法は「【C#】DateTime.Dateで日付部分だけ取得」で解説しています。

こちらの記事も読まれています!


よかったらシェアしてね!
目次
閉じる