LoginSignup
6
6

More than 5 years have passed since last update.

Visual C# 2013 パーフェクトマスター 6章 コレクションとジェネリック

Posted at

Amazon.co.jp: VisualC#2013パーフェクトマスター (Perfect Master SERIES): 金城 俊哉: 本

自分の不明点をとりまとめ。理解できているところは割愛。

配列とコレクション

1次元配列

    int a = new int[10];
    a[4] = 80;

二次元配列

    int a = new int[3,10];
    a[1,4] = 10;

コレクションクラス

ArratListクラスは動的に配列数を変更できる。
コレクションとは複数のオブジェクトをまとめて管理する機能。

            ArrayList col = new ArrayList();
            col.Add("hogehoge");
            col.Add("fugafuga");
            Console.WriteLine(col[1]);

ArrayListクラスのaddはobject型のためキャストが必要な場合がある

            ArrayList col = new ArrayList();
            col.Add(100);
            string text = "hogehoge";
            col[0] = text;
            text = col[0];
            /// 'object' を 'string' に暗黙的に変換できません。
            /// 明示的な変換が存在します。(cast が不足していないかどうかを確認してください)
            /// text = Convert.ToString(col[0]);

ジェネリック

ジェネリックは様々な型に対応するために型をパラメータとして指定し、その型に対応したクラスやメソッドを生成する機能。

Listジェネリッククラス

Listジェネリッククラスではパラメータリストにデータ型を記述することでリストで扱うデータ型が指定できる。
ArryListクラスではキャストが必要だったためListジェネリッククラスの方がパフォーマンス上優れている。

            List<string> list = new List<string>();
            list.Add("100"); /// list.Add(100)ならエラー
            string text = "hogehoge";
            list[0] = text;
            text = list[0];
            Console.WriteLine(list[0]);

Dictionaryクラス

キーと値をペアで管理します

        static void Main(string[] args)
        {
            var obj = new Dictionary<string, int>();
            obj.Add("hogehoge", 10);
            obj.Add("fugafuga", 20);
            Disp(obj);
        }

        static void Disp(Dictionary<string, int> t)
        {
            foreach (var item in t.Keys)
            {
                Console.WriteLine(item, t[item]);
            }

        }

型パラメータを持つクラス

同じ配列を繰り返し使える場合に型毎に配列を宣言せず、型パラメータを使って単一化できる。

namespace ConsoleApplication1
{

    public class ListTest<T>        /// Tは型パラメータ。コンストラクタで指定。
    {
        T[] list = new T[100];      /// Tの型の配列を100個宣言
        int add;                    /// 配列のインデックス値

        public void AddItem(T item) /// 配列格納用のメソッド
        {
            list[add++] = item;     /// add++で呼び出し毎に配列を追加して値を格納
        }

        public T this[int index]    /// インデクサ
        {
            get
            {
                return list[index]; /// indexを指定して呼び出し
            }
            set
            {
                list[index] = value;/// 値をセット
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            ListTest<string> list = new ListTest<string>();

            list.AddItem("1番目");
            list.AddItem("2番目");

            string str1 = list[0];
            Console.WriteLine(str1);

            ListTest<DateTime> dtlist = new ListTest<DateTime>();

            dtlist.AddItem(DateTime.Today);

            DateTime today = dtlist[0];
            Console.WriteLine(today);
        }
    }
}

複数の型パラメータを持つクラス

    class test<T1, T2>
    {
        public T1 val1 { get; set; }
        public T2 val2 { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var a = new test<string, int>();
            var b = new test<int, string>();

            a.val1 = "abc";
            a.val2 = 100;
            b.val1 = 200;
            b.val2 = "xyz";

            Console.WriteLine(a.val1 + "," + a.val2);
            Console.WriteLine(b.val1 + "," + b.val2);
        }
    }

 

ジェネリック・メソッド

型パラメータをメソッドに対して設定してみる

    class Program
    {
        static void Disp<T>(T p)
        {
            Console.WriteLine(p);
        }

        static void Main(string[] args)
        {
            Disp<int>(500);
            Disp<string>("hogehoge");

            Disp(500); /// 型指定は省略可
            Disp("fugafuga");
        }
    }

型パラメーターの命名ガイドライン

型パラメーターは1文字で指定。「T」
複数の型パラメーターを持つ場合はわかりやすく、先頭にTをつける。「TInput,TOutput」等。

イテレーター

クラス内での繰り返し処理を行うforeachステートメントはコードが複雑かつ冗長になる場合がある。
yieldステートメントを利用して簡略化が可能。

    class Program
    {
        public static IEnumerable MethodShow()
        {
            yield return "hogehoge";
            yield return "fugafuga";
            yield return "piyopiyo";
        }

        static void Main(string[] args)
        {
            foreach(string val in Program.MethodShow())
            {
                Console.WriteLine(val);
            }
        }
    }

疑問点

イテレータ

「foreachステートメントはコードが複雑かつ冗長になる場合があるのでイテレーターのyieldステートメントを使う」とあるが、サンプルコードを見る限りforeach文自体はあまり簡略化されてない気がする。
foreachでループするオブジェクトを事前に用意するのじゃなく、その都度メソッドで宣言できるということ?

6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6