2017/03/10

C# : 配列要素のNULLチェック

C#で配列の要素にnullが存在するかをチェックする方法です。



1次元配列にnullが含まれているかチェック

チェック対象が1次元の配列に限定されるなら以下のように、
ArrayのIndexOfメソッドでnullを検索するだけで判定できます。

テストコード:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace NullCheck1D
{
    class Program
    {
        static void Main(string[] args)
        {
            // チェック対象の配列
            Object[] testArray1D = { new object(), new object(), null, new object() };

            // nullの存在をチェック
            if (Array.IndexOf(testArray1D, null) > -1)
            {
                Console.WriteLine("nulあり");
            }
            else
            {
                Console.WriteLine("nulなし");
            }
        }
    }
}



多次元配列に対応

しかし、ArrayのIndexOfメソッドで検索できるのは1次元配列限定なので、
2次元以上の多次元配列(foo[1,2]やbar[1,2,3]のような配列)の配列のnullチェックには使えません。

多次元配列のnullチェックもしたい場合は、多次元配列に対してforeachループを使うと、配列の全要素に対してアクセスできることを利用して、
foreachループ内で配列の要素に対してnullチェックをするようにすれば、配列にnullが含まれているかチェック可能です。

テストコード:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

/// <summary>
/// 多次元配列のnullチェック
/// </summary>
namespace NullCheck2D
{
    class Program
    {
        static void Main(string[] args)
        {
            // チェック対象の配列配列(2次元配列)
            //   ([,]は[2,2]を省略した書き方です)
            Object[,] testArray2D = new Object[,]
            {
                { new Object(), new Object() },
                { null, new Object() }
            };

            // nullの存在をチェック
            if (hasNull(testArray2D))
            {
                Console.WriteLine("nulあり");
            }
            else
            {
                Console.WriteLine("nulなし");
            }
        }

        /// <summary>
        /// 配列のnullチェック
        /// </summary>
        /// <param name="target">チェック対象の配列</param>
        /// <returns>true=nullあり / false=nullなし</returns>
        static bool hasNull(Array target)
        {
            foreach (Object element in target)
            {
                if (element == null)
                {
                    return true;
                }
            }

            return false;
        }
    }
}



ジャグ配列にも対応

1次元配列、多次元配列には対応できましたが、
配列の要素が配列(ジャグ配列)の場合にも対応したい場合は、配列の要素が配列か(ArrayのArray)をチェックする必要があります。

変数が配列かどうかをチェックするには、Type.IsArrayプロパティを使います。
そして、配列だった場合には、その配列に対して配列のnullチェックをします。
配列要素のnullチェック中に、また配列要素のnullチェックが必要となるとややこしく感じますが、チェック処理を関数化しておいて再帰するだけで、以下のように簡単にできます。

テストコード:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

/// <summary>
/// 配列のnullチェック(1次元配列、多次元配列、ジャグ配列)
/// </summary>
namespace NullCheck
{
    class Program
    {
        static void Main(string[] args)
        {
            // チェック対象の配列(2次元+ジャグ)
            Object[,] testArray = new Object[,]
            {
                { new Object(), new Object() },
                { new Object[] { new Object(), null }, new Object() }
            };

            // nullの存在をチェック
            if (hasNull(testArray))
            {
                Console.WriteLine("nulあり");
            }
            else
            {
                Console.WriteLine("nulなし");
            }
        }

        /// <summary>
        /// 配列のnullチェック
        /// </summary>
        /// <param name="target">チェック対象の配列</param>
        /// <returns>true=nullあり / false=nullなし</returns>
        static bool hasNull(Array target)
        {
            foreach (Object element in target)
            {
                if (element == null)
                {
                    return true;
                }

                if (element.GetType().IsArray)
                {
                    //要素が配列の場合は、この配列チェック関数に再帰
                    if (hasNull((Array)element))
                    {
                        return true;
                    }
                }
            }

            return false;
        }
    }
}





配列をnullチェックしたい場面によって、以上のようなパターンを使分けると便利です。

0 件のコメント:

コメントを投稿