【C#と.NETプログラミング】(7)-C#汎用、依頼

11194 ワード

汎用型
  • 基本形式
  • using namespace System.Collections.Generic
    
    //       ( ListList obj = new List();
  • 汎用型を使用できる場合、非汎用型を使用しないでください.主に2つの問題があります.
  • 梱包/解体による効率低下
  • .
  • タイプの安全な
  • ではありません

    一例(『C#の汎型詳細』)
    //         
    
    //        int   
    public class Stack
    {
        private int[] m_item;
        public int Pop(){...}
        public void Push(int item){...}
    
        public Stack(int i)
        {
            this.m_item = new int[i];
        }
    }
    
    //          ,    object
    public class Stack
    {
        private object[] m_item;
        public object Pop(){...}
        public void Push(object item){...}
    
        public Stack(int i)
        {
            this.m_item = new[i];
        } 
    }

    改造されたStackは柔軟になるが1.特定のタイプからobjectへの変換(箱詰め/解体)は効率を低下させる2.objectはすべてのクラスのベースクラスであるため、任意のタイプの入力は正常にコンパイルできますが、タイプがサポートされていないため、実行時エラーが発生する可能性があります.
    汎用的な処理方式
    //        
    public class Stack
    {
        private T[] m_item;
        public T Pop(){...}
    
        public void Push(T item){...}
        public Stack(int i)
        {
            this.m_item = new T[i];
        }
    }
    
    //               
    Stack<int> a = new Stack<int>(100);
    a.Push("a string");    //      

    汎用クラス/インタフェースをサポート
    ネーミングスペースの使用:System.Collections.Generic
    名前
    ツールバーの
    さぎょう
    ICollection
    インタフェース
    すべての汎用集合タイプ定義の基本プロパティ
    IComparer
    インタフェース
    オブジェクト比較
    IDictionary
    インタフェース
    辞書
    IEnumerable
    インタフェース
    IEnumeratorに戻る
    IEnumerator
    インタフェース
    汎用コレクションをforeach形式で反復できるようにする
    IList
    インタフェース
    リスト#リスト#
    ISet
    インタフェース
    しゅうごう
    Dictionary
    クラス#クラス#
    汎用辞書
    List
    クラス#クラス#
    汎用リスト
    LinkedList
    クラス#クラス#
    汎用双方向チェーンテーブル
    Queue
    クラス#クラス#
    汎用キュー
    SortedDictionary
    クラス#クラス#
    並べ替えられた汎用辞書
    SortedSet
    クラス#クラス#
    並べ替えられた重複しない汎用集合
    Stack
    クラス#クラス#
    汎用スタック
    初期化構文
    //     int     List<>
    List<int> myList = new List<int>{0, 2, 1, 3};

    SortedSetクラス
    このクラスのアイテムはソートされており、アイテムの挿入と削除後も自動的にソートが正しいことを確認できます.カスタムクラスに対しては、インタフェースIComparerを実装する必要があります.
    // sortedset<T>
    
    //             IComparer     Compare   
    class SortPerson : IComparer
    {
        public int Compare(Person p1, Person p2)
        {
            //       
            if(p1.Age > p2.Age)
                return 1;
            if(p1.Age < p2.Age)
                return -1;
            else
                reutrn 0;
        }
    }
    
    //     SortSet      age     
    //    SortSet      Person,  SortPerson           
    SortSet setOfPeople = new SortSet(new SortPerson())
    {
        new Person {...},
        new Perosn {...},
        ...
    };

    カスタム汎用の作成
    感覚はC++のテンプレートに似ていますが、両者の違いは後で検討します.
    //                 swap
    static void Swap(ref T a, ref T b)
    {
        T tmp = a;
        a = b;
        b = tmp;
    }

    defaultを使用してデフォルト値を設定します.インスタンス化前に特定のタイプが分からないためです.
    //     default      
    public void resetData<T>(ref T data)
    {
        // default      T           
        data = default(T);
    }

    依頼(Delegate)
    C#の依頼はC/C++の関数ポインタに似ており、イベントやコールバック方法に一般的に使用されます.
    関数ポインタに比べて、委任には次の2つの利点があります.
  • 関数ポインタは静的関数のみを指すが、委任タイプは静的関数も非静的メンバー
  • も参照できる.
  • は、関数ポインタと比較する、委任タイプはオブジェクト向け、タイプ安全の制御対象であり、アドレス境界
  • を心配する必要はない.
    委任タイプの定義
    //       delegate       
    public delegate void BuyTicketEventHandle(int num);
  • 依頼は、intとして出力voidとして入力コマンド
  • を宣言するコマンド(文章大白話シリーズのC#依頼とイベント説明(一)を参照)と見なすことができる.
  • コンパイラは、自動的に派生システムを生成する.MulticastDelegateのシール類.実際にBuyTicketEventHandleはクラス
  • です
    委任タイプの使用
    //   
    
    //    
    public class buybuybuy
    {
        public static void BuyTicket(int num)
            Console.WriteLine("{0} tickets bought");
    }
    
    //    
    public class order
    {
        //       
        public delegate void BuyTicketEventHandle(int num);
    
        public static void Main(string[] args)
        {
            //           
            BuyTicketEventHandle BuyTickets = new BuyTicketEventHandle(buybuybuy.BuyTicket);
    
            BuyTickets(3);
        }
    }

    委任されたマルチキャスト(委任チェーン)
    1つのコマンドチェーンとして理解でき,1つの依頼オブジェクトに複数のメソッドを追加する(もちろん入出力形式は同じである)
    //        
    //    +=   -=
    //         Delegate.Combine()   Delegate.Remove()
    
    //    
    public class buybuybuy
    {
        public static void BuyTicket(int num){
            Console.WriteLine("{0} tickets bought", num);
        }
    
        public static void SellTicket(int num){
            Console.WriteLine("{0} tickets sold", num);
        }
    }
    
    //    
    public class order
    {
        //       
        public delegate void BuyTicketEventHandle(int num);
    
        public static void Main(string[] args)
        {
            //           
            BuyTicketEventHandle ListBuyTickets = new BuyTicketEventHandle(buybuybuy.BuyTicket);
    
            //        
            ListBuyTickets += buybuybuy.SellTicket;
            //       BuyTicket(3)、SellTicket(3)
            ListBuyTickets(3);
    
            //       
            ListBuyTickets -= buybuybuy.BuyTicket;
            //     SellTicket(4)
            ListBuyTickets(4);
    
            Console.ReadKey();
        }
    }

    ここで問題として,メソッドBuyTicketとSellTicketはパラメータ付きであるため,チェーン実行は同一のパラメータセットしか使用できないため,設計時にはなるべく依頼をvoidにして呼び出し関数の入力パラメータとする.
    リファレンス
    【1】C#と.NET 4プレミアムプログラミング(第5版)