連番を省略表記する/省略表記した連番をリストに戻す (C#で)

#連番の省略表記
わかりにくい表現ですが、
`1,2,3,4,5,7,8,9`
という数値のリストを
`1-5,7-9`
という文字列に変換します。あるいはその逆変換をします。

どういうことに使えるかというと、例えば一連番号のあるものの中から抽出したものを人間が読みやすいようにするなんてことに使えます。
読み上げさせる時に、`1から5 7から9`と読めば、`1 2 3 4 5 7 8 9`と読ませるよりも人間にはどれが抽出され、どれが抽出されていないのかというのがすぐに分かります。

```SequenceString.cs
using System;
using System.Collections.Generic;
using System.Runtime.Remoting.Messaging;
using System.Linq;

namespace SequenceString
{
    class ListConverter
    {
        public static string ListToSequenceString(List<Int64> myList,
                                              Char SeparaterCharacter = ',',
                                              Char NaverCharacter = '-')
        {
            string SequenceString = "";
            List<Int64> innerList = myList;
            Int64 Position = -999;
            bool isLastNumber = true;
            try
            {
                innerList.Sort();
            }
            catch
            {
                return "I can not sort this List.";
            }
            foreach (Int64 val in innerList)
            {
                if (Position + 1 == val)
                {
                    if (isLastNumber) SequenceString += NaverCharacter;
                    isLastNumber = false;
                }
                else
                {
                    SequenceString +=
                        String.Format(isLastNumber ? "{1}{2}" : "{0}{2}{1}{2}",
                                      Position, val, SeparaterCharacter);
                    isLastNumber = true;
                }
                Position = val;
            }
            if (!isLastNumber) SequenceString += String.Format("{0}", Position);
            SequenceString =
                SequenceString.Replace(SeparaterCharacter.ToString() + NaverCharacter.ToString(),
                                       NaverCharacter.ToString());
            SequenceString = SequenceString.TrimEnd(SeparaterCharacter);
            return SequenceString;
        }

        public static List<Int64> SequenceStringToList(string SequenceString,
                                                  Char SeparaterCharacter = ',',
                                                  Char NaverCharacter = '-'
                                                  )
        {
            List<Int64> innerList = new List<Int64>();
            try
            {
                foreach (String PartString in SequenceString.Split(SeparaterCharacter))
                {
                    if (PartString.Contains(NaverCharacter.ToString()))
                    {
                        String[] PartStrings = PartString.Split(NaverCharacter);
                        if (PartStrings.Count() == 2)
                        {
                            for (Int64 i = Convert.ToInt64(PartStrings[0]); i <= Convert.ToInt64(PartStrings[1]); i++)
                                innerList.Add(i);
                        }
                    }
                    else
                    {
                        innerList.Add(Convert.ToInt64(PartString));
                    }
                }
            }
            catch (Exception ex)
            {
                throw (ex);
            }
            return innerList;
        }
    }
}
```

これをこんな形で呼び出します。

```MainClass.cs
    class MainClass
    {
        public static void Main(string[] args)
        {
            List<Int64> Test = new List<Int64>();
            Int64[] ar = { 1, 2, 3, 5, 7, 8, 9 };
            Test.AddRange(ar);
            String SequenceString;
            SequenceString =
                ListConverter.ListToSequenceString(
                    Test,
                    SeparaterCharacter: ',',
                    NaverCharacter: '-');
            List<Int64> New = ListConverter.SequenceStringToList(SequenceString, SeparaterCharacter: ',', NaverCharacter: '-');
            Console.WriteLine(SequenceString);
            foreach (int i in New)
                Console.Write(i.ToString() + " ");
        }
    }
```

`Int64`で帰ってくるのはちょっとアレかもしれません。ジェネリックでやろうと思ったら、`Convert.ToInt64()`のところをうまく処理する必要があります。