Architect's Log

I'm a Cloud Architect. I'm highly motivated to reduce toils with driving DevOps.

【.NET】Null安全なStringBuilder.AppendFormatを拡張メソッドで実装する

どういうこと?

String.FormatやStringBuilder.AppendFormatは、パラメータにNullを渡すと例外が発生します。

using System;
using System.Text;

namespace console1 {
    class Program {
        static void Main(string[] args) {
            StringBuilder b = new StringBuilder();

            try {
                b.AppendFormat("value is {0}", null);
            } catch (Exception ex) {
                Console.WriteLine(ex.Message);
                // 出力:値をNullにすることはできません。
            }

            Console.ReadKey();
        }
    }
}

どうすれば?

全部の呼び出し箇所でnullチェックはしたくないので、拡張メソッドでNull安全なAppendFormatを実装します。

using System;
using System.Text;
using System.Linq;

namespace console1 {
    class Program {
        static void Main(string[] args) {
            StringBuilder b = new StringBuilder();

            b.NullSafeAppendFormat("value is {0}", "hoge").AppendLine();
            b.NullSafeAppendFormat("value is {0}", null).AppendLine();
            b.NullSafeAppendFormat("value is {0} and {1}", "hoge", null).AppendLine();
            Console.WriteLine(b.ToString());
            // 出力:
            // value is hoge
            // value is Null
            // value is hoge and Null

            Console.ReadKey();
        }
    }

    public static class StringBuilderExtensions {
        public static StringBuilder NullSafeAppendFormat(
            this StringBuilder self, 
            string format, 
            params object[] args) {

            object[] parameters;
            if (args is Array) {
                parameters = args;
            } else {
                parameters = new object[] { args };
            }

            var array = parameters.Select(p => p ?? "Null").ToArray();

            return self.AppendFormat(format, array);
        }
    }
}