developer's diary

最近はc#のエントリが多いです

C# (dotnetcore)で標準出力を利用して進行中のスピナーを作る (1)

どんなものか

コンソールでくるくる回って、進捗りつ表示するアニメーションです。

f:id:mitsugi-bb:20200823084247g:plain
スピナー

gifアニメにしてみたんですが、少しわかりにくいですね・・・

youtubeにしてみた

youtu.be

単純に出力するプログラム

using System;

namespace example_Spinner
{
    class Program
    {
        static void Main(string[] args)
        {
            //アニメーションのコマ
            string[] bars = { "⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏" };

            //色変更
            Console.ForegroundColor = ConsoleColor.Green;
            Console.BackgroundColor = ConsoleColor.Black;

            //0〜99まで繰り返す
            for (int i = 0; i < 100; i++)
            {
                //アニメーションの表示
                Console.Write(bars[i % bars.Length]);
                //進捗率の表示
                Console.Write("{0, 3:d0}%", i + 1);
                //カーソル位置を変更
                Console.SetCursorPosition(0, Console.CursorTop);
                //一時停止
                System.Threading.Thread.Sleep(50);
            }

            //色を戻す
            Console.ResetColor();

            //カーソル位置を変更
            Console.SetCursorPosition(0, Console.CursorTop);

            //終了の表示
            Console.WriteLine("Done! ");
        }
    }
}

これを使えるものにしたい

.netのProgressBarのような部品にしたいので、 ProgressBarでよく使うプロパティ、メソッドを列挙してみる。

項目 種類 説明
Minimum プロパティ コントロールの範囲の最小値を取得または設定します。
Maximum プロパティ コントロールの範囲の最大値を取得または設定します。
Value プロパティ プログレス バーの現在位置を取得または設定します。
Step プロパティ PerformStep() メソッドを呼び出したときに、プログレス バーの現在の位置を進める量を取得または設定します。
PerformStep メソッド プログレス バーの現在位置を Step プロパティの値の分だけ進めます。

クラスを作る

    /// <summary>コンソール用の</summary>
    class ConsoleProgressSpiner
    {
        /// <summary>コントロールの範囲の最小値を取得または設定します。</summary>
        public int Minimum { get; set; }

        /// <summary>コントロールの範囲の最大値を取得または設定します。</summary>
        public int Maximum { get; set; }

        /// <summary>プログレス バーの現在位置を取得または設定します。</summary>
        public int Value { get; set; }

        /// <summary>PerformStep() メソッドを呼び出したときに、プログレス バーの現在の位置を進める量を取得または設定します。</summary>
        public int Step { get; set; }

        /// <summary>プログレス バーの現在位置を Step プロパティの値の分だけ進めます。 </summary>
        public void PerformStep()
        {

        }
    }

Minimumプロパティの実装

ProgressBar.Minimum プロパティを参考に。

既定値は 0 です。

        /// <summary>コントロールの範囲の最小値を取得または設定します。</summary>
        public int Minimum { get; set; } = 0;

テストケースも追加

        [Fact]
        public void MinimumDefaultTest()
        {
            ConsoleProgressSpiner c = new ConsoleProgressSpiner();
            Assert.Equal(0, c.Minimum);
        }

プロパティに対して指定された値が 0 未満の場合に、例外をスローする

Minimumプロパティのゲッター、セッターを修正

        private int minimum = 0;

        /// <summary>コントロールの範囲の最小値を取得または設定します。</summary>
        public int Minimum {
            get
            {
                return minimum;
            }
            set
            {
                if ((value < 0))
                    throw new ArgumentException("プロパティに対して指定された値が 0 未満です。");

                minimum = value;
            }
        }

テストケースを追加

        [Fact]
        public void MinimumSetterArgumentExceptionTest()
        {
            ConsoleProgressSpiner c = new ConsoleProgressSpiner();
            var ex = Assert.Throws<ArgumentException>(() =>
            {
                c.Minimum = -1;
            });
            Assert.IsType<ArgumentException>(ex);
            Assert.Equal("プロパティに対して指定された値が 0 未満です。", ex.Message);
        }

ひとまず。ここまで。続きは次回。

mitsugeek.net