【C#と.NETプログラミング】(7)-C#汎用、依頼
11194 ワード
汎用型基本形式 汎用型を使用できる場合、非汎用型を使用しないでください.主に2つの問題があります. 梱包/解体による効率低下 .タイプの安全な ではありません
一例(『C#の汎型詳細』)
改造されたStackは柔軟になるが1.特定のタイプからobjectへの変換(箱詰め/解体)は効率を低下させる2.objectはすべてのクラスのベースクラスであるため、任意のタイプの入力は正常にコンパイルできますが、タイプがサポートされていないため、実行時エラーが発生する可能性があります.
汎用的な処理方式
汎用クラス/インタフェースをサポート
ネーミングスペースの使用:System.Collections.Generic
名前
ツールバーの
さぎょう
ICollection
インタフェース
すべての汎用集合タイプ定義の基本プロパティ
IComparer
インタフェース
オブジェクト比較
IDictionary
インタフェース
辞書
IEnumerable
インタフェース
IEnumeratorに戻る
IEnumerator
インタフェース
汎用コレクションをforeach形式で反復できるようにする
IList
インタフェース
リスト#リスト#
ISet
インタフェース
しゅうごう
Dictionary
クラス#クラス#
汎用辞書
List
クラス#クラス#
汎用リスト
LinkedList
クラス#クラス#
汎用双方向チェーンテーブル
Queue
クラス#クラス#
汎用キュー
SortedDictionary
クラス#クラス#
並べ替えられた汎用辞書
SortedSet
クラス#クラス#
並べ替えられた重複しない汎用集合
Stack
クラス#クラス#
汎用スタック
初期化構文
SortedSetクラス
このクラスのアイテムはソートされており、アイテムの挿入と削除後も自動的にソートが正しいことを確認できます.カスタムクラスに対しては、インタフェースIComparerを実装する必要があります.
カスタム汎用の作成
感覚はC++のテンプレートに似ていますが、両者の違いは後で検討します.
defaultを使用してデフォルト値を設定します.インスタンス化前に特定のタイプが分からないためです.
依頼(Delegate)
C#の依頼はC/C++の関数ポインタに似ており、イベントやコールバック方法に一般的に使用されます.
関数ポインタに比べて、委任には次の2つの利点があります.関数ポインタは静的関数のみを指すが、委任タイプは静的関数も非静的メンバー も参照できる.は、関数ポインタと比較する、委任タイプはオブジェクト向け、タイプ安全の制御対象であり、アドレス境界 を心配する必要はない.
委任タイプの定義依頼は、intとして出力voidとして入力コマンド を宣言するコマンド(文章大白話シリーズのC#依頼とイベント説明(一)を参照)と見なすことができる.コンパイラは、自動的に派生システムを生成する.MulticastDelegateのシール類.実際にBuyTicketEventHandleはクラス です
委任タイプの使用
委任されたマルチキャスト(委任チェーン)
1つのコマンドチェーンとして理解でき,1つの依頼オブジェクトに複数のメソッドを追加する(もちろん入出力形式は同じである)
ここで問題として,メソッドBuyTicketとSellTicketはパラメータ付きであるため,チェーン実行は同一のパラメータセットしか使用できないため,設計時にはなるべく依頼をvoidにして呼び出し関数の入力パラメータとする.
リファレンス
【1】C#と.NET 4プレミアムプログラミング(第5版)
using namespace System.Collections.Generic
// ( List )
List obj = new List();
一例(『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);
委任タイプの使用
//
//
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版)