【C# 拡張メソッド】nullをToString()

nullToString()すると見事に落ちます。
とはいえ、イチイチチェックするのは面倒ですよね。

そこで、拡張メソッドを使って簡単回避する方法をご紹介します。

目次

【C# 拡張メソッド】nullをToString()

例外が発生するソースコード例

public class Test
{
    public void Main()
    {
        DateTime? nullDate = null;
        var formated = nullDate.ToString();
        Console.WriteLine($"formated   : '{ValueOf(formated)}'");

        string nullString = null;
        var formated2 = nullString.ToString(); // ←これはSystem.NullReferenceExceptionになる
        Console.WriteLine($"formated2  : '{ValueOf(formated2)}'");
    }

    /// <summary>
    /// nullなら文字列"null"を返す
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public string ValueOf(object obj)
    {
        return (obj == null) ? "null" : obj.ToString();
    }
}

// 【実行結果】
// formated   : ''
// 例外がスローされました: 'System.NullReferenceException'

ちょっと想定外のことが起きました。
nullDate.ToString();でも落ちる想定だったんですが、今は“”が返ってくるんですね。
string型を.ToString()することは無いと思いますが、こちらは今でも見事に落ちます。
環境は「Visual Studio Community 2017」です。
でも、古い環境では落ちる人もいますよね?

では、気を取り直して。拡張メソッドを見ていきましょう。

拡張メソッド

public static class ObjectExtensions
{
    /// <summary>
    /// <para>null値をToStringする</para>
    /// <para>nullの場合、nullを返す</para>
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value"></param>
    /// <param name="format"></param>
    /// <returns>書式設定された値またはnull</returns>
    public static string ToStringOrDefault(this object value, string format = "")
    {
        if (value != null)
        {
            return string.Format("{0:" + format + "}", value);
        }
        return null;
    }

    /// <summary>
    /// <para>null値をToStringする</para>
    /// <para>nullの場合、空を返す</para>
    /// </summary>
    /// <param name="value"></param>
    /// <param name="format"></param>
    /// <returns>書式設定された値または空</returns>
    public static string ToStringOrEmpty(this object value, string format = "")
    {
        if (value != null)
        {
            return string.Format("{0:" + format + "}", value);
        }
        return string.Empty;
    }
}

他にも便利な拡張メソッドを知りたい方は「【C#】拡張メソッド まとめ」のページをどうぞ。

使い方①

public class Test
{
    public void Main()
    {
        // ToStringOrDefault()メソッド
        Console.WriteLine($"【 ToStringOrDefault()メソッド 】");

        Console.WriteLine($"   null");
        DateTime? nullDate = null;
        var formated = nullDate.ToStringOrDefault();
        var formated2 = nullDate.ToStringOrDefault("yyyyMMdd");
        Console.WriteLine($"        formated   format無し  : '{ValueOf(formated)}'");
        Console.WriteLine($"        formated2  yyyyMMdd    : '{ValueOf(formated2)}'");

        Console.WriteLine($"   null以外");
        DateTime? nullableDate = DateTime.Now;
        var formated3 = nullableDate.ToStringOrDefault();
        var formated4 = nullableDate.ToStringOrDefault("yyyy/MM/dd");
        Console.WriteLine($"        formated3  format無し  : '{formated3}'");
        Console.WriteLine($"        formated4  yyyy/MM/dd    : '{formated4}'");


        // ToStringOrEmpty()メソッド
        Console.WriteLine($"【 ToStringOrEmpty()メソッド 】");

        Console.WriteLine($"   null");
        var formated5 = nullDate.ToStringOrEmpty();
        var formated6 = nullDate.ToStringOrEmpty("yyyyMMdd");
        Console.WriteLine($"        formated5  format無し  : '{formated5}'");
        Console.WriteLine($"        formated6  yyyyMMdd    : '{formated6}'");

        Console.WriteLine($"   null以外");
        var formated7 = nullableDate.ToStringOrEmpty();
        var formated8 = nullableDate.ToStringOrEmpty("yyyy/MM/dd");
        Console.WriteLine($"        formated7  format無し  : '{formated7}'");
        Console.WriteLine($"        formated8  yyyy/MM/dd    : '{formated8}'");
    }

    /// <summary>
    /// nullなら文字列"null"を返す
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public string ValueOf(object obj)
    {
        return (obj == null) ? "null" : obj.ToString();
    }
}

// 【実行結果】
// 【 ToStringOrDefault()メソッド 】
//    null
//         formated   format無し  : 'null'
//         formated2  yyyyMMdd    : 'null'
//    null以外
//         formated3  format無し  : '2019/12/24 9:35:40'
//         formated4  yyyy/MM/dd    : '2019/12/24'
// 
// 【 ToStringOrEmpty()メソッド 】
//    null
//         formated5  format無し  : ''
//         formated6  yyyyMMdd    : ''
//    null以外
//         formated7  format無し  : '2019/12/24 9:35:40'
//         formated8  yyyy/MM/dd    : '2019/12/24'

nullを考慮したうえで、string.Formatの処理と、nullまたは“”を返す処理が出来るようになりました。

念のため、先ほどのnullString.ToString();についても確認します。

使い方②

public class Test
{
    public void Main()
    {
        string nullString = null;
        var formated2 = nullString.ToStringOrDefault();
        Console.WriteLine($"formated2  : '{ValueOf(formated2)}'");

        var formated3 = nullString.ToStringOrEmpty();
        Console.WriteLine($"formated3  : '{ValueOf(formated3)}'");
    }

    /// <summary>
    /// nullなら文字列"null"を返す
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public string ValueOf(object obj)
    {
        return (obj == null) ? "null" : obj.ToString();
    }
}

// 【実行結果】
// formated2  : 'null'
// formated3  : ''

問題ありませんでした。
string→stringの型変換をすることは無いと思いますが、null“”に変換したい際は使えるかもしれません。

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

参考サイト

How can I format a nullable DateTime with ToString()?


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