|
.NET TIPS
長いジェネリック・クラスの名前を短く記述するには?[2.0のみ、C#、VB]
デジタルアドバンテージ 遠藤 孝信
2006/04/28 |
|
|
「TIPS:ハッシュテーブル(Dictionaryクラス)を値でソートするには?」で示しているサンプル・プログラムのように、ジェネリック・クラスを使ったコーディングは、各行が長く複雑になりがちだ。
例えば、型パラメータに文字列型と整数型を指定するKeyValuePair構造体(System.Collections.Generic名前空間)の要素を持つListクラス(System.Collections.Generic名前空間)は次のように記述しなければならない。
List<KeyValuePair<string, int>>
|
List(Of KeyValuePair(Of String, Integer))
|
|
KeyValuePair構造体の要素を持つListクラスの記述(上:C#、下:VB) |
このような記述が煩雑な場合には、C#ではusingディレクティブ、VBではImportsステートメントを用いてクラス名に短い別名を付け、その別名を用いてコードを簡潔に記述できる。
まず以下に別名の定義例を示す。
using StrIntList =
System.Collections.Generic.List<
System.Collections.Generic.KeyValuePair<string, int>>;
|
Imports StrIntList = _
System.Collections.Generic.List(Of _
System.Collections.Generic.KeyValuePair(Of String, Integer))
|
|
別名の定義例(上:C#、下:VB) |
usingやImportsは通常、利用するクラスの名前空間の指定に用いられるが、別名の定義はこれらのキーワードが持つ、もう1つの機能だ。
このような別名を多用すれば、以下のようなコードの書き換えが可能となる(書き換え後の完全なソース・コードは後掲)。
Dictionary<string, int> dict = new Dictionary<string, int>();
makeDict(dict);
List<KeyValuePair<string, int>> sorted = sortByValue(dict);
foreach (KeyValuePair<string, int> kvp in sorted) {
Console.WriteLine(kvp.Key + ":" + kvp.Value);
}
|
StrIntDict dict = new StrIntDict();
makeDict(dict);
StrIntList sorted = sortByValue(dict);
foreach (StrIntPair kvp in sorted) {
Console.WriteLine(kvp.Key + ":" + kvp.Value);
}
|
|
別名によるC#のコード書き換え例 |
上:元のコード
下:ジェネリック・クラスに対して別名を使用したコード |
Dim dict As New Dictionary(Of String, Integer)
makeDict(dict)
Dim sorted As List(Of KeyValuePair(Of String, Integer)) = sortByValue(dict)
For Each kvp As KeyValuePair(Of String, Integer) In sorted
Console.WriteLine(kvp.Key & ":" & kvp.Value)
Next
|
Dim dict As New StrIntDict()
makeDict(dict)
Dim sorted As StrIntList = sortByValue(dict)
For Each kvp As StrIntPair In sorted
Console.WriteLine(kvp.Key & ":" & kvp.Value)
Next
|
|
別名によるVBのコード書き換え例 |
上:元のコード
下:ジェネリック・クラスに対して別名を使用したコード |
このようにジェネリック・クラスに対して別名を使用すると、ジェネリック・クラスであっても非ジェネリック・クラスのように扱うことができ、コードもかなりすっきりする。
もちろん別名の定義は非ジェネリック・クラスに対しても可能であり、.NET Framework 1.0のころより使える機能であるが、ジェネリック・クラスの登場により、その有用性が増したといえるだろう。
以下には、「TIPS:ハッシュテーブル(Dictionaryクラス)を値でソートするには?」のサンプル・プログラム全体を、別名を使って書き換えたものを示しておく。
// genericalias.cs
using System;
using System.Net;
using System.Text.RegularExpressions;
using System.Collections.Generic;
// ジェネリック・クラスに対する別名の定義
using StrIntPair =
System.Collections.Generic.KeyValuePair<string, int>;
using StrIntDict =
System.Collections.Generic.Dictionary<string, int>;
using StrIntList =
System.Collections.Generic.List<
System.Collections.Generic.KeyValuePair<string, int>>;
//////////////////////////////////////////////////
class GenericAlias {
static void makeDict(StrIntDict dict) {
string html;
// HTMLの取得
using (WebClient wc = new WebClient()) {
html = wc.DownloadString("http://www.atmarkit.co.jp/");
}
// 単語に分割して、各単語の出現頻度をカウント
foreach (string s in Regex.Split(html, "\\W")) {
string word = s.Trim();
if (word != "") {
if (dict.ContainsKey(word)) {
dict[word]++;
} else {
dict[word] = 1;
}
}
}
}
static void Main() {
StrIntDict dict = new StrIntDict();
makeDict(dict);
StrIntList sorted = sortByValue(dict);
// sorted.Reverse(); // 逆順にする場合
foreach (StrIntPair kvp in sorted) {
Console.WriteLine(kvp.Key + ":" + kvp.Value);
}
// 出力例:
// a:542
// td:394
// 0:328
// width:289
// tr:284
// ……
}
static StrIntList sortByValue(StrIntDict dict) {
StrIntList list = new StrIntList(dict);
// Valueの大きい順にソート
list.Sort(
delegate(StrIntPair kvp1, StrIntPair kvp2) {
return kvp2.Value - kvp1.Value;
});
return list;
}
}
// コンパイル方法:csc genericalias.cs
|
|
別名を使って書き換えたC#のサンプル・プログラム(genericalias.cs) |
|
' genericalias.vb
Imports System
Imports System.Net
Imports System.Text.RegularExpressions
Imports System.Collections.Generic
' ジェネリック・クラスに対する別名の定義
Imports StrIntPair =
System.Collections.Generic.KeyValuePair(Of String, Integer)
Imports StrIntDict =
System.Collections.Generic.Dictionary(Of String, Integer)
Imports StrIntList =
System.Collections.Generic.List(Of
System.Collections.Generic.KeyValuePair(Of String, Integer))
''''''''''''''''''''''''''''''''''''''''''''''''''
Class DictionarySortByValue
Shared Sub makeDict(ByVal dict As StrIntDict)
Dim html As String
' HTMLの取得
Using wc As New WebClient()
html = wc.DownloadString("http://www.atmarkit.co.jp/")
End Using
' 単語に分割して、各単語の出現頻度をカウント
For Each s As String In Regex.Split(html, "\W")
Dim word As String = s.Trim()
If Not word = "" Then
If dict.ContainsKey(word) Then
dict(word) += 1
Else
dict(word) = 1
End If
End If
Next
End Sub
Shared Sub Main()
Dim dict As New StrIntDict()
makeDict(dict)
Dim sorted As StrIntList = sortByValue(dict)
' sorted.Reverse() ' 逆順にする場合
For Each kvp As StrIntPair In sorted
Console.WriteLine(kvp.Key & ":" & kvp.Value)
Next
' 出力例:
' a:542
' td:394
' 0:328
' width:289
' tr:284
' ……
End Sub
Shared Function hikaku(ByVal kvp1 As StrIntPair, ByVal kvp2 As StrIntPair) As Integer
' Valueの大きい順にソート
Return kvp2.Value - kvp1.Value
End Function
Shared Function sortByValue(ByVal dict As StrIntDict) As StrIntList
Dim list As New StrIntList(dict)
list.Sort(AddressOf hikaku)
Return list
End Function
End Class
' コンパイル方法:vbc genericalias.vb
|
|
別名を使って書き換えたVBのサンプル・プログラム(genericalias.vb) |
|
なお、usingやImportsにより別名を定義する際には、ほかで定義した別名や、名前空間名を省略したクラス名をその定義に含めることはできない。このため、このサンプル・プログラムのように、別名の定義部分だけは各行が長くなってしまう。
利用可能バージョン:.NET Framework 2.0のみ
カテゴリ:C# 処理対象:言語構文
カテゴリ:Visual Basic 2005 処理対象:言語構文
使用ライブラリ:Dictionaryクラス(System.Collections.Generic名前空間)
使用ライブラリ:KeyValuePair構造体(System.Collections.Generic名前空間)
使用ライブラリ:Listクラス(System.Collections.Generic名前空間)
関連TIPS:ハッシュテーブル(Dictionaryクラス)を値でソートするには?
|
|
generated by
|
|
Insider.NET 記事ランキング
本日
月間