コレクションはOOPにおいて重要な概念であり、C#でのコレクションへの完全サポートはこの言語の中でも特に優れた点の一つです。
なぜ汎用セットを使うのか? C# 2.0以前は、コレクションは主に2つの方法で実装できました。 a. ArrayList の使用 オブジェクトを直接ArrayListに入れるのは直感的ですが、コレクション内のアイテムがObject型なので、使うたびに面倒な型変換が必要です。 b. カスタムコレクションクラスを使用する 一般的な手法としては、CollectionBase抽象クラスからカスタムクラスを継承し、IListオブジェクトをカプセル化して強力な型コレクションを実装することです。 この方法は、各コレクションタイプに対応するカスタムクラスを書く必要があり、非常に手間がかかります。 ジェネリックコレクションの登場により、上記の問題はよく解決され、指定された型の集合を作成するためにコードは1行だけで済みます。 ジェネリックとは何でしょうか? ジェネリックはC# 2.0の新しい要素(C++ではテンプレートと呼ばれる)で、主に類似の問題の連続を解決するために使われます。 この仕組みにより、クラス名を引数としてジェネリック型に渡し、対応するオブジェクトが生成されます。 ジェネリック(クラス、インターフェース、メソッド、デリゲートなどを含む)はテンプレートとして考える方が良いかもしれません。ここでバリアント部分はクラス名を引数として渡すものに置き換え、新しい型定義を生み出します。 ジェネリックは比較的大きなテーマであり、ここでは詳細に分析しません。興味のある方は関連情報をご参照ください。 ジェネリックコレクションはどうやって作成すればいいですか? System.Collections.Generic 名前空間の下にあるList genericクラスは<T>コレクション作成に使用され、構文は以下の通りです: [mw_shl_code=cシャープ、真]リスト<T>ListOfT = 新しいリスト<T>(); [/mw_shl_code] 「T」は使用される型で、文字列、整数型、またはユーザー定義型などの単純な型でもよくあります。 具体的な例を見てみましょう。
パーソンクラスは次のように定義されます。 [mw_shl_code=csharp、true]クラス
{ プライベートストリング_name; 名称 プライベート・インタ_age; 年代
Person オブジェクトを作成 公的人物(文字列名、int 年齢) { this._name= 名前; this._age = 年齢; }
名称 公開文字列名 { get { return _name; } }
年代 パブリック・イン・エイジ { get { return _age; } }
}
//创建Person对象 人物p1=新しい人物(「張三」、30); 人物p2=新しい人物(「李思」、20); 人 p3 = 新しい人(「王武」、50);
//创建类型为Person的对象集合 リスト<Person> 人物 = 新しいリスト<Person>();
//将Person对象放入集合 人。 Add(p1); 人。 Add(p2); 人。 Add(p3);
//输出第2个人的姓名 Console.Write(persons[1]. 名前); [/mw_shl_code] ご覧の通り、ジェネリックコレクションはコレクションの実装コードを大幅に簡素化し、指定された型のコレクションを簡単に作成できます。 それだけでなく、汎用コレクションはより強力な機能も提供します。ここでは、それらのソートや検索を見てみましょう。 ジェネリックコレクションのソート ソートは比較に基づいており、ソートするにはまず比較が必要です。 例えば、1と2の数字がある場合、それらをソートするにはまずこれらを比較し、比較結果に従ってソートする必要があります。 オブジェクトを比較したい場合、状況は少し複雑です。例えば、Personオブジェクトを比較する場合は名前や年齢で比較でき、比較ルールを決める必要があります。 オブジェクトは複数の比較ルールを持つことができますが、デフォルトルールは1つだけで、そのルールはそのオブジェクトを定義するクラスに配置されます。 デフォルトの比較ルールは、IComparable汎用インターフェースに属するCompareToメソッドで定義されています<T>。 以下のコードをご覧ください: [mw_shl_code=csharp,true]クラス 人名:IComparable<Person>
{ 年齢別比較 public int CompareTo(Person p) { これを返せ。 年齢 - p.年齢; } }[/mw_shl_code] CompareToメソッドのパラメータは、比較対象となる同じタイプの別のオブジェクトです。返り値はint型です。返り値が0より大きい場合は最初のオブジェクトが2番目のオブジェクトより大きいことを意味し、戻り値が0未満なら最初のオブジェクトが2番目のオブジェクトより小さいことを意味します。0を返すなら、2つのオブジェクトは等しいです。 デフォルトの比較ルールを定義した後、パラメータなしでSortメソッドを使ってコレクションをソートできます。以下のように: [mw_shl_code=csharp,true]// コレクションをデフォルトルールに従ってソートしてください 人。 Sort();
//输出所有人姓名 foreach(人称p in persons)
{ コンソール.WriteLine(p.Name); 出力順は「李四」「張三」「王武」です。 }[/mw_shl_code] 実際には、コレクションをさまざまな異なるルールに従ってソートする必要があることが多く、それには他の比較ルールの定義が必要となります。これらはIComparerジェネリックインターフェースに属するCompareメソッドで定義できます<T>。以下のコードを参照してください。 [mw_shl_code=csharp,true]クラス名比較器:IComparer<Person>
{ ストレージシーケンサーインスタンス 公開の静的NameComparer Default = new NameComparer();
名称で比較 パブリック・イント比較(人物p1、人物p2) { System.Collections.Comparer.Default.Compare(p1. 名前、p2。 名前); } }[/mw_shl_code] Compareメソッドのパラメータは、比較対象となる同じタイプの2つのオブジェクトであり、返り値はint型、返還値の処理ルールはCompareToメソッドと同じです。 Comparer.Defaultは、同じタイプの2つのオブジェクトを比較するための組み込みのComparerオブジェクトを返します。 この新たに定義された比較器を使ってコレクションをソートする方法は以下の通りです: [mw_shl_code=csharp,true]//コレクションを名前で並べ替える 人。 Sort(NameComparer.Default);
//输出所有人姓名 foreach(人称p in persons)
{ コンソール.WriteLine(p.Name); 出力順は「李四」「王武」「張三」です。 }[/mw_shl_code] コレクションを委任することでソートすることもできます。まずは、代理が比較ルールを保存するためのメソッドを定義し、静的メソッドを使うこともできます。 以下のコードをご覧ください: [mw_shl_code=csharp,true]クラス PersonComparison
{ 名称で比較 公開静的 int Name(Person p1, Person p2) { System.Collections.Comparer.Default.Compare(p1. 名前、p2。 名前); } }[/mw_shl_code] このメソッドのパラメータは比較対象となる同じタイプの2つのオブジェクトで、返却値はint型、返却値処理ルールはCompareToメソッドと同じです。その後、組み込みの汎用代理システムを使ってコレクションをソートします。比較<T>: [mw_shl_code=cシャープ、真]System.Comparison<Person> NameComparison = 新しいSystem.Comparison<Person>(PersonComparison.Name); 人。 Sort(NameComparison);
//输出所有人姓名 foreach(人称p in persons)
{ コンソール.WriteLine(p.Name); 出力順は「李四」「王武」「張三」です。 }[/mw_shl_code] 後者2つの方法は指定されたルールに従ってコレクションをソートできますが、著者は委任法を好んでおり、クラスに様々な比較ルールを配置し、柔軟に呼び出すことも検討できます。 ジェネリックコレクションの検索 検索はコレクションから特定の条件を満たすアイテムを見つけるためのものであり、必要に応じて複数の検索条件を定義・呼び出すことができます。 まず、検索条件を次のように定義します。 [mw_shl_code=csharp,true]クラスPerson述語
{ 中年(40歳以上)の方を探す public static bool MidAge(Person p) { もし(p.年齢>=40) 真を返す; そうでなければ Return false; } }[/mw_shl_code] 上記の検索条件は、ブール返却型の静的メソッドに配置され、特定の条件を満たすアイテムは真を返し、そうでなければ偽を返します。その後、組み込みのジェネリック代理ツールSystem.Predicateを使ってコレクションを検索します<T>: [mw_shl_code=cシャープ、真]System.Predicate<Person> MidAgePredicate = 新しいSystem.Predicate<Person>(PersonPredicate.MidAge); リスト<Person> ミッドエイジ ピープルズ = パーソナルズ。 FindAll(中世述語);
//输出所有的中年人姓名 foreach(中年期の人称p)
{ コンソール.WriteLine(p.Name); アウトプット「ワン・ウー」 }[/mw_shl_code] ジェネリックコレクションの拡張 セット内の全員の名前をカンマで区切って表示したい場合はどうでしょうか? 単一のクラスが提供できる機能に制限があることを考えると、Listクラスを拡張するのが自然に考えられます<T>。Listクラスもクラスであり、継承によって拡張可能です。 以下のコードをご覧ください: [mw_shl_code=csharp,true]// Persons コレクションクラスを定義する 階級 人物:リスト<Person>
{ コレクションに入っている全員の名前を出せ 公開文字列GetAllNames() { もし(これ。 カウント == 0) 「返す」;
文字列 val = ""; foreach(ここでの人称p) { val += p.Name + ","; }
戻って、ヴァル。 サブストリング(0, val. 長さ - 1); }
}
//创建并填充Persons集合 Persons PersonCol = 新しいPersons(); PersonCol.Add(p1); PersonCol.Add(p2); PersonCol.Add(p3);
//输出所有人姓名 Console.Write(PersonCol.GetAllNames()); アウトプット「張三、李思、王武」[/mw_shl_code] 概要: 本記事は、C# 2.0におけるジェネリックの活用によるコレクションの実装やコレクション機能の拡張に焦点を当てており、ジェネリックコレクションの適切な活用は多くの重複作業を減らし、開発効率を大幅に向上させることができます。 実際、セットはジェネリックの典型的な応用に過ぎず、ジェネリックについてもっと知りたい場合は、他の関連資料を参照することができます。 この記事がお役に立てば幸いです :-)
|