<?xml version="1.0" encoding="UTF-8" ?> <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>十兵衛＠わんくま同盟</title><link>http://blogs.wankuma.com/jubei/</link><description>十兵衛のネタ Powered Blog</description><managingEditor>十兵衛（諸農）</managingEditor><dc:language>ja-JP</dc:language><generator>.Text Version 0.95.2004.102</generator><item><dc:creator>十兵衛（諸農）</dc:creator><title>時間は掛かるけど・・・</title><link>http://blogs.wankuma.com/jubei/archive/2009/05/09/172670.aspx</link><pubDate>Sat, 09 May 2009 08:42:00 GMT</pubDate><guid>http://blogs.wankuma.com/jubei/archive/2009/05/09/172670.aspx</guid><wfw:comment>http://blogs.wankuma.com/jubei/comments/172670.aspx</wfw:comment><comments>http://blogs.wankuma.com/jubei/archive/2009/05/09/172670.aspx#Feedback</comments><slash:comments>34</slash:comments><wfw:commentRss>http://blogs.wankuma.com/jubei/comments/commentRss/172670.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/jubei/services/trackbacks/172670.aspx</trackback:ping><description>&lt;p&gt;ディレクトリ/フォルダのように階層構造を持つデータ群から特定のデータを探し出したり、またはドライブに含まれる全部のファイルやディレクトリを列挙したいときにはどうすればいいでしょうか。forやwhileを使った繰り返し処理で検索するファイルやディレクトリが無くなるまで処理を続けると言った方法が思い付きます。 &lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private void SearchFiles()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DirectoryInfo root = new DirectoryInfo(@"C:\Windows");&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FileInfo[] dirInfos = root.GetFiles("*.*", SearchOption.AllDirectories);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (FileInfo di in dirInfos) Console.WriteLine(di.Name);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/p&gt; &lt;p&gt;.NET v2.0で追加されたDirectoryInfo.GetFiles（）のオーバーロードバージョンを使えば、検索対象の配下のすべてのディレクトリ/ファイルを一気に取得できます※１。データを取得するだけではなく、階層構造の単位で何らかの処理をしたい、と言った場合にはちょっとよいしょが必要ですね。例えば階層構造に合わせてTreeViewに表示したい場合なら、取得したFileInfoからディレクトリの構造を抜き出してTreeViewに追加するノードを作ったり、すでにあるノードからディレクトリのノードを探し出してファイル名のノードを追加する、みたいな感じで、ちょっと考えただけでも頭の中がこんがらがってしまいそうです。 &lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;em&gt;※１　ドライブを検索対象にした場合、System Volume へのアクセス権限がないと次のような例外が発生します。&lt;br&gt;&amp;nbsp; System.UnauthorizedAccessException はハンドルされませんでした。&lt;br&gt;&amp;nbsp; Message="パス 'C:\\System Volume Information' へのアクセスが拒否されました。"&lt;br&gt;&amp;nbsp; Source="mscorlib"&lt;/em&gt; &lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;ディレクトリ/フォルダの構成というのは、いくつかのディレクトリ/フォルダが階層というルールに従って並んでいるだけです。一つのディレクトリ/フォルダに対して行う処理は全部のディレクトリ/フォルダに行う処理と同じです。ただ、その処理が階層的に連続しているだけと言うことに気付きます。ということは、このディレクトリ/フォルダ単位に行う処理を繰り返し行えば目的を達成することが出来そうです。 &lt;/p&gt; &lt;p&gt;まず最小単位の処理を考えてみます。最小単位はフォルダに対する処理です。一つのフォルダの中に含まれるフォルダとファイルの一覧を列挙する処理を作ります。フォルダに含まれるファイルを列挙するのは簡単ですが、そのフォルダの配下にあるフォルダ、つまり階層構造の次の階層のフォルダの処理はどうすればいいのでしょうか。次の階層に行う処理も、今自分が行っている処理も、処理の手順は同じと言うことに気付けば簡単です。今行っている処理と同じ処理をもう一度呼び出せば良いのです。そうすると呼び出される処理は、自分が行うべき対象のフォルダの情報を呼び出し側から受け取って処理を行い、処理の過程で新たにフォルダを発見したなら、そのフォルダの情報を使ってもう一度自分自身と同じ処理を呼び出せばよいと言うことになります。このように最小単位に分けられた処理が、その処理の中から繰り返し呼び出されることを再帰処理、または単に再帰と呼びます。 &lt;/p&gt; &lt;p&gt;再帰処理を使う場面は階層構造をもったデータに対してだけではありません。例えば単純な場面では、いくつか並んだ数字の中に特定の数字がいくつ含まれているかをチェックする場合にも使えます。 &lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private int HowManyNumber(int value,int Target)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (value == 0) return 0;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return (((value % 10) == Target) ? 1 : 0) + HowManyNumber(value / 10, Target);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private void button1_Click(object sender, EventArgs e)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int num = 37453863;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int target = 3;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine("{0}の中に{1}は{2}個ありました",&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; num,target, HowManyNumber(num, target));&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/p&gt; &lt;p&gt;応用すれば、約数/公約数や因数分解にも利用できます。 &lt;/p&gt; &lt;p&gt;自分自身を繰り返し呼び出すことになる再帰処理には無限ループに陥るという危険性がありますから、どこかで必ず終わることが出来るように終了条件を決めておくことを忘れてはいけません。また、再帰処理は自分自身を繰り返し呼びことになるので、呼び出しの階層が深くなればなるに従って処理の中で使うメモリも少しずつ積み重なり増え続けることになります。計算対象が大きくなればなるほど消費するリソースの量が増え続けて、最悪の場合はリソース不足から処理そのものが中断されてしまうことになります。 &lt;/p&gt; &lt;p&gt;再帰処理は高速なアルゴリズム、とは言えないです。何度も繰り返しメソッドを呼び出すのですから呼び出しのオーバーヘッドが処理の速度にも影響するでしょう。リソースも消費するのでそれだけマシンそのものの負荷増大にも繋がります。再帰処理のメリットは、プログラムの見やすさにあると考えても良さそうです。 &lt;/p&gt; &lt;p&gt;最初の話に戻って、ディレクトリ/ファイル一覧をTreeViewに表示するのに次のような処理を使ってみました。再帰処理の最小単位となる処理の内容は、受け取ったディレクトリの情報からそのディレクトリに含まれるディレクトリ一覧とファイル一覧を取得しディレクトリのノードを作成します。ノードを作成したディレクトリの情報を使ってもう一度自分自身を呼びます。この時に、作成したディレクトリのノードも引き渡します。そうすることで受け取った側は、引き渡されたディレクトリ情報からそのディレクトリ内に含まれるディレクトリを一階層上のノードに子ノードとして追加することが出来ます。ディレクトリがなければファイル一覧のノードが追加されます。 &lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private string[] SearchDrives()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; List&amp;lt;string&amp;gt; driveStr = new List&amp;lt;string&amp;gt;();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DriveInfo[] drives = DriveInfo.GetDrives();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (DriveInfo di in drives)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (di.IsReady)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; driveStr.Add(string.Format("{0} [{1}]", di.Name, di.VolumeLabel));&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; driveStr.Add(string.Format("{0}", di.Name));&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return driveStr.ToArray();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private TreeNode SearchFiles(DirectoryInfo ADirInfo,TreeNode ANode)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DirectoryInfo[] dirInfos = ADirInfo.GetDirectories();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (DirectoryInfo di in dirInfos)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ((di.Attributes &amp;amp; FileAttributes.System) &amp;gt; 0) continue;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TreeNode node = ANode.Nodes.Add(di.Name);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SearchFiles(di, node);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FileInfo[] fileInfos = ADirInfo.GetFiles();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (FileInfo fi in fileInfos) ANode.Nodes.Add(fi.Name);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return ANode;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/p&gt; &lt;p&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private void Linear()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; treeView1.Nodes.Clear();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string drive = (string)comboBox1.Items[comboBox1.SelectedIndex];&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; drive = drive.Substring(0, 3);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DriveInfo di = new DriveInfo(drive);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (di.IsReady)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; treeView1.BeginUpdate();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TreeNode root = treeView1.Nodes.Add(di.Name);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DirectoryInfo dirInfo = new DirectoryInfo(di.Name);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SearchFiles(dirInfo, root);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; root.Expand();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; treeView1.TopNode = root;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; finally&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; treeView1.EndUpdate();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/p&gt; &lt;p&gt;フォーム上に配置したComboBoxにドライブ一覧が表示されていて、ComboBox上の選択アイテムが変更されたときに起動するようにしています。ドライブ情報の取得方法は次の通りです。 &lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private string[] SearchDrives()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; List&amp;lt;string&amp;gt; driveStr = new List&amp;lt;string&amp;gt;();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DriveInfo[] drives = DriveInfo.GetDrives();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (DriveInfo di in drives)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (di.IsReady)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; driveStr.Add(string.Format("{0} [{1}]", di.Name, di.VolumeLabel));&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; driveStr.Add(string.Format("{0}", di.Name));&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return driveStr.ToArray();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private void Form1_Load(object sender, EventArgs e)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; comboBox1.Items.AddRange(SearchDrives());&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Linear();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/p&gt; &lt;p&gt;この方法ではドライブ内のディレクトリ/ファイルの一覧を延々と検索するのですが、ドライブに含まれるディレクトリ/ファイルの数が多すぎると、処理を行っている最中はフォームが無応答、つまり固まったように見えます。 &lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;a href="http://jubei.wankuma.com/images/14cbbbb005df_7A46/cap0195.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px" border="0" alt="cap0195" src="http://jubei.wankuma.com/images/14cbbbb005df_7A46/cap0195_thumb.png" width="331" height="189"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;この現象は時間の掛かる処理をフォームを作成したスレッドと同じスレッドで行っているのが原因です。この固まったように見える現象をデリゲートの非同期実行によって回避してみましょう。ComboBoxのアイテム選択が変更され、ディレクトリ/ファイル一覧を作成するデリゲートを作成しBeginInvoke()で非同期実行を開始します。この時、非同期で実行されるデリゲートが終了した時点で呼び出されるコールバックメソッドも指定しておきます。処理が終了したらコールバックメソッドが呼び出されるので、コールバックメソッドの中でデリゲートの戻り値、つまりディレクトリ/ファイル一覧のTreeNodeを受け取ります。そして受け取ったTreeNodeをTreeViewにセットするのですが、コールバックメソッドはフォームとは違うスレッドで実行されているので、コールバックメソッドの中からフォーム上のコントロールには直接アクセスすることはできません。そこで、フォームと同じスレッドで実行されるデリゲートを作成しフォームのInvoke/BeginInvokeメソッドに処理を委譲する、つまりデリゲートします。この時、匿名メソッドを使えば、コールバックメソッド内で受け取ったTreeNode変数をメソッドの外で定義する必要が無くなり、一つのメソッド内で完結させることが出来ます。 &lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;a href="http://jubei.wankuma.com/images/14cbbbb005df_7A46/cap0196.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px" border="0" alt="cap0196" src="http://jubei.wankuma.com/images/14cbbbb005df_7A46/cap0196_thumb.png" width="336" height="328"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private delegate TreeNode SeachFileDelegate(DirectoryInfo ADirInfo, TreeNode ANode);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private delegate void InvokeDelegate(); &lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private void Asynchronous()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; treeView1.Nodes.Clear();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string drive = (string)comboBox1.Items[comboBox1.SelectedIndex];&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; drive = drive.Substring(0, 3);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DriveInfo di = new DriveInfo(drive);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (di.IsReady)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TreeNode root = new TreeNode(di.Name);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DirectoryInfo dirInfo = new DirectoryInfo(di.Name);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SeachFileDelegate sfd = new SeachFileDelegate(SearchFiles);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sfd.BeginInvoke(dirInfo,root,new AsyncCallback(CallBack),sfd);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private void CallBack(IAsyncResult ar)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SeachFileDelegate sfd = (SeachFileDelegate)ar.AsyncState;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TreeNode root = sfd.EndInvoke(ar);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.BeginInvoke(new InvokeDelegate(&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; delegate()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; treeView1.BeginUpdate();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; treeView1.Nodes.Add(root);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; treeView1.Nodes[0].Expand();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; treeView1.TopNode = root;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; finally&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; treeView1.EndUpdate();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; })&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; );&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/p&gt; &lt;p&gt;&amp;nbsp; &lt;/p&gt; &lt;p&gt;&amp;nbsp; &lt;/p&gt; &lt;p&gt;さてさて、実生活においても、これくらい非同期で色んなことが出来たらいいのに・・・と思うのは、僕だけかしらん(^^; &lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/jubei/aggbug/172670.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>十兵衛（諸農）</dc:creator><title>ストリーム型プロパティ</title><link>http://blogs.wankuma.com/jubei/archive/2009/05/09/172657.aspx</link><pubDate>Sat, 09 May 2009 07:26:00 GMT</pubDate><guid>http://blogs.wankuma.com/jubei/archive/2009/05/09/172657.aspx</guid><wfw:comment>http://blogs.wankuma.com/jubei/comments/172657.aspx</wfw:comment><comments>http://blogs.wankuma.com/jubei/archive/2009/05/09/172657.aspx#Feedback</comments><slash:comments>128</slash:comments><wfw:commentRss>http://blogs.wankuma.com/jubei/comments/commentRss/172657.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/jubei/services/trackbacks/172657.aspx</trackback:ping><description>&lt;p&gt;読み取り専用のストリーム型プロパティを作成した場合、getアクセッサの実装をどうするか。&lt;br&gt;&lt;br&gt;コンストラクタでもらったオーディオストリームをコピーして内部で保持しておき、必要なときにSoundPlayerで演奏するつもりで、内部で保持しているストリームオブジェクトの参照をそのままreturnすると負けます。 &lt;p&gt;private class MyClass&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private System.IO.Stream audio;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public System.IO.Stream Data&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return audio;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }  &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public MyClass(System.IO.Stream AAudio)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; audio = new System.IO.MemoryStream();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; AAudio.WriteTo(audio);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;}  &lt;p&gt;&amp;nbsp; private void DoPlay()&lt;br&gt;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SoundPlayer snd = new System.Media.SoundPlayer();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; snd.LoadCompleted += new AsyncCompletedEventHandler(LoadCompleted);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; snd.Stream = obj.Data;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; snd.LoadAsync();&lt;br&gt;&amp;nbsp; }  &lt;p&gt;&amp;nbsp; private void LoadCompleted(object sender,System.ComponentModel.AsyncCompletedEventArgs e)&lt;br&gt;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; while (!snd.IsLoadCompleted) System.Threading.Thread.Sleep(5);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; snd.PlaySync();&lt;br&gt;&amp;nbsp; } &lt;p&gt;一回目はちゃんと演奏できますけど、二回目以降は「WAVヘッダが壊れています」と言うメッセージが出ます。&lt;br&gt;なぜなら、SoundPlayerが一度演奏すると、ストリームのポジションが終わりに到達しているからなんです。参照をもらっているのでオブジェクト側のストリームも終端に達していると言うわけで、この終端に達した状態でもう一度SoundPlayerに読み込ませても、SoundPlayerは先頭に巻き戻しをしない。その場所から演奏を開始しようとする。なのでエラーになっちゃう。&lt;br&gt;渡す前に巻き戻しをするか、新しくStreamオブジェクトを作成してreturnするか。今回の場合はgetアクセッサだけを装備した読み取り専用プロパティという意味もあるので、新しくStreamを作った方が良いと思います。外部操作で中身が変更されてしまっては、読み取り専用の意味がなくなりますね。 &lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/jubei/aggbug/172657.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>十兵衛（諸農）</dc:creator><title>配列を扱う（C#のArray型）</title><link>http://blogs.wankuma.com/jubei/archive/2009/05/09/172656.aspx</link><pubDate>Sat, 09 May 2009 07:21:00 GMT</pubDate><guid>http://blogs.wankuma.com/jubei/archive/2009/05/09/172656.aspx</guid><wfw:comment>http://blogs.wankuma.com/jubei/comments/172656.aspx</wfw:comment><comments>http://blogs.wankuma.com/jubei/archive/2009/05/09/172656.aspx#Feedback</comments><slash:comments>48</slash:comments><wfw:commentRss>http://blogs.wankuma.com/jubei/comments/commentRss/172656.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/jubei/services/trackbacks/172656.aspx</trackback:ping><description>&lt;p&gt;.NET Frameworkでは、一次元配列のリサイズがstaticメソッドで簡単にできます。また、Fileクラスを使ってテキストデータを直接読み込むことも出来ます。&lt;br&gt;この二つを組み合わせれば、ファイルのテキストデータを文字列配列として確保することが出来ます。 &lt;/p&gt; &lt;p&gt;今回の「配列を扱う」テストのために準備したテキストデータは、一つの国名を「漢字」「ひらがな」「カタカナ」の順に半角スペースで区切って一行に記載したものです。&lt;br&gt;準備した国名は全部で29個ですが、二つのファイルに分割して保存しています。 &lt;/p&gt; &lt;p&gt;読み込みデータ１ &lt;/p&gt; &lt;table border="1" cellspacing="3" cellpadding="3" bgcolor="#c0c0c0"&gt; &lt;tbody&gt; &lt;tr valign="top"&gt; &lt;td&gt;露西亜 &lt;/td&gt; &lt;td&gt;ろしあ &lt;/td&gt; &lt;td&gt;ロシア &lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td&gt;英吉利 &lt;/td&gt; &lt;td&gt;いぎりす &lt;/td&gt; &lt;td&gt;イギリス &lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td&gt;日本 &lt;/td&gt; &lt;td&gt;にっぽん &lt;/td&gt; &lt;td&gt;ニッポン &lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td&gt;阿弗利加 &lt;/td&gt; &lt;td&gt;あふりか &lt;/td&gt; &lt;td&gt;アフリカ &lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td&gt;独逸 &lt;/td&gt; &lt;td&gt;どいつ &lt;/td&gt; &lt;td&gt;ドイツ &lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td&gt;印度 &lt;/td&gt; &lt;td&gt;いんど &lt;/td&gt; &lt;td&gt;インド &lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td&gt;濠太剌利 &lt;/td&gt; &lt;td&gt;おーすとらりあ &lt;/td&gt; &lt;td&gt;オーストラリア &lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td&gt;亜米利加 &lt;/td&gt; &lt;td&gt;あめりか &lt;/td&gt; &lt;td&gt;アメリカ &lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td&gt;阿蘭陀 &lt;/td&gt; &lt;td&gt;おらんだ &lt;/td&gt; &lt;td&gt;オランダ &lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td&gt;白耳義 &lt;/td&gt; &lt;td&gt;べるぎー &lt;/td&gt; &lt;td&gt;ベルギー &lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td&gt;伯剌西爾 &lt;/td&gt; &lt;td&gt;ぶらじる &lt;/td&gt; &lt;td&gt;ブラジル &lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td&gt;加奈陀 &lt;/td&gt; &lt;td&gt;かなだ &lt;/td&gt; &lt;td&gt;カナダ &lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td&gt;仏蘭西 &lt;/td&gt; &lt;td&gt;ふらんす &lt;/td&gt; &lt;td&gt;フランス &lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td&gt;伊太利亜 &lt;/td&gt; &lt;td&gt;いたりあ &lt;/td&gt; &lt;td&gt;イタリア &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;読み込みデータ２ &lt;/p&gt; &lt;table border="1" cellspacing="3" cellpadding="3" bgcolor="#c0c0c0"&gt; &lt;tbody&gt; &lt;tr valign="top"&gt; &lt;td&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td&gt;瑞西 &lt;/td&gt; &lt;td&gt;すいす &lt;/td&gt; &lt;td&gt;スイス &lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td&gt;西班牙 &lt;/td&gt; &lt;td&gt;すぺいん &lt;/td&gt; &lt;td&gt;スペイン &lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td&gt;葡萄牙 &lt;/td&gt; &lt;td&gt;ぷろとがる &lt;/td&gt; &lt;td&gt;ポルトガル &lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td&gt;墺太利 &lt;/td&gt; &lt;td&gt;おーすとりあ &lt;/td&gt; &lt;td&gt;オーストリア &lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td&gt;瑞典 &lt;/td&gt; &lt;td&gt;すうぇーでん &lt;/td&gt; &lt;td&gt;スウェーデン &lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td&gt;諾威 &lt;/td&gt; &lt;td&gt;のるうぇー &lt;/td&gt; &lt;td&gt;ノルウェー &lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td&gt;芬蘭 &lt;/td&gt; &lt;td&gt;ふぃらんど &lt;/td&gt; &lt;td&gt;フィンランド &lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td&gt;丁抹 &lt;/td&gt; &lt;td&gt;でんまーく &lt;/td&gt; &lt;td&gt;デンマーク &lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td&gt;希臘 &lt;/td&gt; &lt;td&gt;ぎりしゃ &lt;/td&gt; &lt;td&gt;ギリシャ &lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td&gt;波蘭 &lt;/td&gt; &lt;td&gt;ぽーらんど &lt;/td&gt; &lt;td&gt;ポーランド &lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td&gt;墨西哥 &lt;/td&gt; &lt;td&gt;めきしこ &lt;/td&gt; &lt;td&gt;メキシコ &lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td&gt;玖馬 &lt;/td&gt; &lt;td&gt;きゅーば &lt;/td&gt; &lt;td&gt;キューバ &lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td&gt;亜爾然丁 &lt;/td&gt; &lt;td&gt;あるぜんちん &lt;/td&gt; &lt;td&gt;アルゼンチン &lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td&gt;智利 &lt;/td&gt; &lt;td&gt;ちり &lt;/td&gt; &lt;td&gt;チリ &lt;/td&gt;&lt;/tr&gt; &lt;tr valign="top"&gt; &lt;td&gt;秘露 &lt;/td&gt; &lt;td&gt;ぺるー &lt;/td&gt; &lt;td&gt;ペルー &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br&gt;&lt;br&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static string[] ArrayConcat()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //国名辞書の読み込み&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string dir = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string[] dicStr = File.ReadAllLines(&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Path.Combine(dir,"Country name.dic"), Encoding.Default); &lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string[] temp = File.ReadAllLines(&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Path.Combine(dir,"Country name2.dic"), Encoding.Default);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //配列データの連結&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int pos = dicStr.Length;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Array.Resize&amp;lt;string&amp;gt;(ref dicStr, pos + temp.Length);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Array.Copy(temp, 0, dicStr, pos, temp.Length); &lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //中身確認&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DisplayArray&amp;lt;string&amp;gt;(dicStr); &lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return dicStr;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/p&gt; &lt;p&gt;&lt;a href="http://jubei.wankuma.com/images/CArray_677F/cap0192.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px" border="0" alt="cap0192" src="http://jubei.wankuma.com/images/CArray_677F/cap0192_thumb.png" width="472" height="345"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;複数の配列を連結したらやっぱりソートですね。ソートはデリゲートを使って行いました。 &lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static SortKey key = SortKey.Kanji; &lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static string[] ArraySort()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string[] dicStr = ArrayConcat();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //ソート&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; key = SortKey.Kana;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Array.Sort&amp;lt;string&amp;gt;(dicStr, Comparison); &lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DisplayArray&amp;lt;string&amp;gt;(dicStr); &lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return dicStr;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static int Comparison(string x, string y)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string[] strX = x.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string[] strY = y.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return strX[(int)key].CompareTo(strY[(int)key]);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/p&gt; &lt;p&gt;ここでは、読み込んだ文字列のソートをどの要素で行うかを列挙型のSortKey で判定するようにしています。この列挙型は別のクラスでも使いたいのでinternal で宣言しています。 &lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; internal enum SortKey { Kanji = 0, Hira = 1, Kana = 2 }; &lt;/p&gt; &lt;p&gt;列挙型は数値型にキャストして利用することが出来るので、Comparisonデリゲートの内部で引き渡された文字列をスペースで分割した後に取得できる文字列の配列のどの要素で比較するのかのインデックスに利用しています。 &lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return strX&lt;strong&gt;&lt;font color="#ff0000"&gt;[(int)key]&lt;/font&gt;&lt;/strong&gt;.CompareTo(strY&lt;strong&gt;&lt;font color="#ff0000"&gt;[(int)key]&lt;/font&gt;&lt;/strong&gt;); &lt;/p&gt; &lt;p&gt;&lt;a href="http://jubei.wankuma.com/images/CArray_677F/cap0193.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px" border="0" alt="cap0193" src="http://jubei.wankuma.com/images/CArray_677F/cap0193_thumb.png" width="489" height="358"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;配列に格納したデータから要素を見つけ出すには BinarySearch() メソッドが使えます。BinarySearch()メソッドではIComparer&amp;lt;T&amp;gt;の実装を通して比較検索を行うことが出来ます。実装するためのクラスを作ります。クラスには先ほどのSortKey 列挙型をプロパティに持たせませます。public int Compare(string x, string y) のyパラメータにBinarySearch()メソッドで指定されるvalueパラメータが引き渡されます。xパラメータには配列の要素が順に引き渡されますので、Compare()メソッドの中身ではxパラメータだけを分解するようにします。 &lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; internal class DicComparer : IComparer&amp;lt;string&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //BinarySearchに渡されたキーワードはyパラメータになる&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public int Compare(string x, string y)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string[] strX = x.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return strX[(int)key].CompareTo(y);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private SortKey key = SortKey.Kanji;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public SortKey Key&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; set { key = value; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return key; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/p&gt; &lt;p&gt;BinarySearch()メソッドでは検索オブジェクトが見つかればその要素のインデックスを返しますが、配列内に同じ要素が複数ある場合はどの要素のインデックスが返されるかは判らないです。バイナリサーチなので仕方がないですね。検索対象の要素が配列に存在しない場合、返される値は0以下の数字になります。この数字を補数演算すると、もしも検索対象の要素が配列内に存在していたとするなら、配列内のどこに位置していたかを知ることが出来ます。 &lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static void BinarySearch()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string[] dicStr = ArraySort();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; switch (key)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; case SortKey.Kanji:&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine("漢字で国名を入力してください");&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; case SortKey.Kana:&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine("カタカナで国名を入力してください");&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; default:&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine("ひらがなで国名を入力してください");&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string keyStr = Console.ReadLine(); &lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //検索&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DicComparer dicComp = new DicComparer();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dicComp.Key = key;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int ret = Array.BinarySearch&amp;lt;string&amp;gt;(dicStr, keyStr, dicComp); &lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (ret &amp;gt; -1)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine("{0}を{1}番目に発見しました", keyStr, ret);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine("詳細情報 = {0}", dicStr[ret]);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ret = ~ret;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine("{0}は発見できませんでした", keyStr);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (ret == 0)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine("{0}は{1}よりも小さいです", keyStr, dicStr[ret]);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(ret == dicStr.Length)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine("{0}は{1}よりも大きいです", keyStr, dicStr[ret-1]);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine("{0}は{1}と{2}の間に入ります", keyStr, dicStr[ret - 1], dicStr[ret]);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/p&gt; &lt;p&gt;&lt;a href="http://jubei.wankuma.com/images/CArray_677F/cap0194.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px" border="0" alt="cap0194" src="http://jubei.wankuma.com/images/CArray_677F/cap0194_thumb.png" width="519" height="379"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;この他にも配列型を扱うArrayクラスには Predicate&amp;lt;T&amp;gt; デリゲートを使った検索メソッドのExists()、Find()、FindAll()、FindIndex()、FindLast()、FindLastIndex()メソッドやAction&amp;lt;T&amp;gt;デリゲートを配列の各要素に適用させるForEach()メソッドが準備されています。 &lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/jubei/aggbug/172656.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>十兵衛（諸農）</dc:creator><title>VBは難しい</title><link>http://blogs.wankuma.com/jubei/archive/2009/05/09/172655.aspx</link><pubDate>Sat, 09 May 2009 07:16:00 GMT</pubDate><guid>http://blogs.wankuma.com/jubei/archive/2009/05/09/172655.aspx</guid><wfw:comment>http://blogs.wankuma.com/jubei/comments/172655.aspx</wfw:comment><comments>http://blogs.wankuma.com/jubei/archive/2009/05/09/172655.aspx#Feedback</comments><slash:comments>10</slash:comments><wfw:commentRss>http://blogs.wankuma.com/jubei/comments/commentRss/172655.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/jubei/services/trackbacks/172655.aspx</trackback:ping><description>&lt;p&gt;最近はプログラムを書くことがほとんどないのですが、燃えさかるプロジェクトのヘルプに入るとどうしてもメンテナンスすることになります。&lt;br&gt;ウチの会社の場合、大体のプロジェクトで採用されているのがVBな訳ですが、やっぱりVBは難しいです。&lt;br&gt;C#的発想でVBに取り組むとハマってしまうことも多々あります。&lt;br&gt;&lt;br&gt;そんな一つが「IIf関数」。&lt;br&gt;SDKの定義では次のようになっています。  &lt;p&gt;Public Function IIf( _&lt;br&gt;&amp;nbsp;&amp;nbsp; ByVal Expression As Boolean, _&lt;br&gt;&amp;nbsp;&amp;nbsp; ByVal TruePart As Object, _&lt;br&gt;&amp;nbsp;&amp;nbsp; ByVal FalsePart As Object _&lt;br&gt;) As Object  &lt;p&gt;第一引数に評価式を指定して、その式の結果が真の時は第二引数で指定したオブジェクトが、偽の時は第三引数で指定したオブジェクトが返されるというわけです。C#的発想だと「?:」演算子が思い浮かぶんですけど。。。今日ハマったのは、DataRowのあるカラムかNullならスペースを返し、Nullでないならカラムの内容を返すと言った部分で、C#だとこんな感じで問題なくできるんですよね。  &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DataTable tbl = new DataTable();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; tbl.Columns.Add("COL1");&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; tbl.Columns.Add("COL2");&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; tbl.Columns.Add("COL3");&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; tbl.Columns.Add("COL4");&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DataRow r = tbl.NewRow();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string s = r[0] == DBNull.Value? "NULL":(string)r[0];&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MessageBox.Show(s);  &lt;p&gt;で、同じようにVB.NETでも書いてみました。  &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim r As DataRow = tbl.NewRow()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim s As String = IIf(r(0) Is DBNull.Value, "", CStr(r(0)))&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MessageBox.Show(s)  &lt;p&gt;一通りのコーディングが済んでテストじゃテストじゃってなことで実行させてみると、なんといきなり例外が発生するんですよ。  &lt;p&gt;'System.InvalidCastException' のハンドルされていない例外が microsoft.visualbasic.dll で発生しました。&lt;br&gt;追加情報 : 型 'DBNull' から型 'String' へのキャストが有効ではありません。  &lt;p&gt;え？何？何？何が悪いの？あ～意味がわから～～～ん、なのです。なんで？なんで？頭の上には？が10個以上並びましたよ。ホントに。全く判りませんでしたね。まさかね、IIf関数が、先に全部実行するなんて思いもしなかったですよ。えぇ、その後泣きながらコードを修正しましたよ。くそっ。&lt;br&gt;他にも色々とハマったことがあって、配列宣言の時に配列要素数を指定する場合は確保したい要素数よりも一つ少ない数字を指定するのとか。二次元配列オブジェクトのLengthを見てみると倍の長さが返ってくるとか。。  &lt;p&gt;さて、こんな私の強い味方が、この本です。  &lt;p&gt;&lt;iframe style="width: 120px; height: 240px" marginheight="0" src="http://rcm-jp.amazon.co.jp/e/cm?t=jubeiprogramm-22&amp;amp;o=9&amp;amp;p=8&amp;amp;l=as1&amp;amp;asins=4873111072&amp;amp;fc1=000000&amp;amp;IS2=1&amp;amp;lt1=_blank&amp;amp;lc1=0000ff&amp;amp;bc1=000000&amp;amp;bg1=ffffff&amp;amp;f=ifr" frameborder="0" marginwidth="0" scrolling="no"&gt;&lt;/iframe&gt;&lt;/p&gt; &lt;p&gt;定価1,800円ということで、技術系書籍にしてはかなりお手頃な価格なんですけど、C#とVB.NET言語の基本的な項目がコンパクトにまとめられているのと、両言語の相違点とハマりがちなツボをよく押さえているので費用対効果は抜群だと思います。さっきのIIf関数についても解説がありました。ウソかホントか知りませんが、IIf関数は通常のIF文よりも実行速度が最大で300倍ほど遅くなる可能性があるそうです（P.41）。  &lt;p&gt;いや、ホントにね、この本がなければクラスのプロパティ宣言すら出来なかったりするんですよ(^^;&lt;br&gt;かなり、重宝しています。&lt;br&gt;オライリー様々って感じです。 &lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/jubei/aggbug/172655.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>十兵衛（諸農）</dc:creator><title>偶数か、奇数か。</title><link>http://blogs.wankuma.com/jubei/archive/2009/05/09/172654.aspx</link><pubDate>Sat, 09 May 2009 07:10:00 GMT</pubDate><guid>http://blogs.wankuma.com/jubei/archive/2009/05/09/172654.aspx</guid><wfw:comment>http://blogs.wankuma.com/jubei/comments/172654.aspx</wfw:comment><comments>http://blogs.wankuma.com/jubei/archive/2009/05/09/172654.aspx#Feedback</comments><slash:comments>39</slash:comments><wfw:commentRss>http://blogs.wankuma.com/jubei/comments/commentRss/172654.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/jubei/services/trackbacks/172654.aspx</trackback:ping><description>&lt;p&gt;ある整数が偶数か奇数かを判断するのは簡単ですね。１の位の数字が「０，２，４，６，８」なら偶数、そうでないなら奇数です。計算式で言うなら、２で割り切ることが出来れば偶数、割り切れなければ奇数と言うことになります。では、プログラムのコードで偶数か奇数かの判定をするにはどうすればいいのでしょうか。単純に２で割ればいいと言うことではないんです。例えば「15」が偶数かどうかを、単純に２で割るコードで確認してみると次のような結果になります。  &lt;p&gt;private void DevideNum()&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int num = 15;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.Diagnostics.Trace.WriteLine(&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string.Format("15 devide 2 is {0}", num / 2));&lt;br&gt;}  &lt;p&gt;&lt;a href="http://jubei.wankuma.com/images/71ec729e283b_64E2/devide001.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px" border="0" alt="devide001" src="http://jubei.wankuma.com/images/71ec729e283b_64E2/devide001_thumb.png" width="181" height="63"&gt;&lt;/a&gt;  &lt;p&gt;コードを実行した結果は「７」※になってしまいました。もちろん人間の脳みそでならコレは奇数だとすぐに判断が出来るのですが、プログラムにはこれだけの情報で偶数か奇数かの判定はできません。もう少し突っ込んで考えないとダメですね。ある整数を２で割った場合、偶数の場合は余りが０になり、奇数の場合は余りが１になると言うことに気付けばとっても簡単です。剰余演算子の「％」を使えば余りを求めることが出来るので、偶数か奇数の判定をしたい整数を２で割ったときの余りを求めて、その余りが０なのか１なのかを確認すれば良いと言うことになります。&lt;br&gt;※オペランドによって出力結果は変わります。  &lt;p&gt;private void DevideNum()&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int num = 15;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.Diagnostics.Trace.WriteLine(&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string.Format("15 is Even ? {0}", (num % 2)==0));&lt;br&gt;}  &lt;p&gt;&lt;a href="http://jubei.wankuma.com/images/71ec729e283b_64E2/devide002.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px" border="0" alt="devide002" src="http://jubei.wankuma.com/images/71ec729e283b_64E2/devide002_thumb.png" width="164" height="58"&gt;&lt;/a&gt;  &lt;p&gt;剰余を求める以外にも、別のやりかたで判定する方法があります。それはビットを見るという方法です。具体的には０ビット目（最下位ビット）を確認するのです。０ビット目が立っていなければ偶数、立っていれば奇数なので、判定の方法としては、判定したい整数と1との論理積を取ってその結果が０ならば偶数、１ならば奇数であると判断ができるのです。  &lt;p&gt;private bool IsEven(int ATarget)&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return (ATarget &amp;amp; 1) == 0;&lt;br&gt;}  &lt;p&gt;private void CheckNumber()&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int num;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; num = 4;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.Diagnostics.Trace.WriteLine(&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string.Format("{0} is {1}", num,IsEven(num)?"Even":"Odd"));&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; num = 35481;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.Diagnostics.Trace.WriteLine(&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string.Format("{0} is {1}", num, IsEven(num) ? "Even" : "Odd"));  &lt;p&gt;}  &lt;p&gt;&lt;a href="http://jubei.wankuma.com/images/71ec729e283b_64E2/devide003.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px" border="0" alt="devide003" src="http://jubei.wankuma.com/images/71ec729e283b_64E2/devide003_thumb.png" width="153" height="74"&gt;&lt;/a&gt;  &lt;p&gt;なんとなくかっこいいでしょ？ &lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/jubei/aggbug/172654.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>十兵衛（諸農）</dc:creator><title>スプラッシュフォーム</title><link>http://blogs.wankuma.com/jubei/archive/2009/05/09/172653.aspx</link><pubDate>Sat, 09 May 2009 07:07:00 GMT</pubDate><guid>http://blogs.wankuma.com/jubei/archive/2009/05/09/172653.aspx</guid><wfw:comment>http://blogs.wankuma.com/jubei/comments/172653.aspx</wfw:comment><comments>http://blogs.wankuma.com/jubei/archive/2009/05/09/172653.aspx#Feedback</comments><slash:comments>736</slash:comments><wfw:commentRss>http://blogs.wankuma.com/jubei/comments/commentRss/172653.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/jubei/services/trackbacks/172653.aspx</trackback:ping><description>&lt;p&gt;スプラッシュフォームを使うと現在の状態が処理の完了待ちであることを表現することが出来ます。しかしメインの処理が完全にブロックするような場合、スプラッシュフォーム側の表示更新もメインの処理に引きずられるようにブロックされてしまい、本来の目的である「待ち状態を表現する」ことが難しくなります。例えば次のようなコードの場合、処理回数をメッセージ文字列としてスプラッシュフォーム上に表示していますが、ブロックされる処理がブロックから解放されるタイミングでしかメッセージ文字列の更新が出来ません。  &lt;p&gt;private void SyncProc()&lt;br&gt;{&lt;br&gt;&lt;strong&gt;//スプラッシュフォーム&lt;/strong&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Form3 f = new Form3();&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; f.Show();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int i = 0; i &amp;lt; 10; i++)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&lt;strong&gt;//ブロックされる処理をシミュレート&lt;/strong&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Thread.Sleep(1000);  &lt;p&gt;&lt;strong&gt;//ブロックから解放されるタイミングでしかメッセージの更新が出来ない&lt;br&gt;&lt;/strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; f.StepProg(&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string.Format("{0:d4} 回目の処理を行いました", i));&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; f.Close();&lt;br&gt;}  &lt;p&gt;このような場合に別のスレッドを作成し、そのスレッド内でスプラッシュフォームの更新を行うようにしてみてはいかがでしょうか。&lt;br&gt;スプラッシュフォーム側にスレッドメソッドを作成しておき、その中でスプラッシュフォームのインスタンスを作成するようにしておきます。オーバーロードバージョンのコンストラクタを作成しておき必要なパラメータを受け取ります。コンストラクタからスプラッシュが表示されている間に行う繰り返し処理が記述されたメソッドを呼び出します。  &lt;p&gt;public static void ThreadMethod(object AParam)&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ThreadParam param = (ThreadParam)AParam;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; new Form2(param.Parent, param.ProgressMin, param.ProgressMax, param.ProgressStep);&lt;br&gt;}  &lt;p&gt;public Form2(Form1 AForm, int Min, int Max, int Step)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; : this()&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; min = Min;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; max = Max;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; step = Step;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; parent = AForm;  &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SyncDoWork();&lt;br&gt;}  &lt;p&gt;private void SyncDoWork()&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.Show();  &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int i = 0; true; i++)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!this.Visible) break;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Thread.Sleep(100);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; progressBar1.PerformStep();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; label1.Text = string.Format("{0:d4} 回目の処理を行いました", i);&lt;br&gt;&lt;strong&gt;//メインの処理は完了したか？&lt;/strong&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ((parent.InvokeRequired) ?&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (bool)parent.Invoke(new GetBool(parent.Done)) : parent.Done()) break;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Application.DoEvents();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }  &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; label1.Text = "メインフォームの処理が完了しました";&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.Update();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Thread.Sleep(1000);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; label1.Text = "スプラッシュフォームを閉じます";&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.Update();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Thread.Sleep(1000);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.Close();&lt;br&gt;}  &lt;p&gt;v2.0からスレッド開始デリゲートに汎用型のパラメータを一つ渡すことが出来るようになりました。複数個のパラメータが必要な場合は、パラメータをプロパティまたはフィールドに持つクラスを定義して汎用オブジェクトとしてスレッドスタートの呼び出し時に引き渡すようにします。  &lt;p&gt;const int max = 10;&lt;br&gt;private void StartThread1()&lt;br&gt;{&lt;br&gt;&lt;strong&gt;//パラメータ&lt;/strong&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ThreadParam param = new ThreadParam(this, 0, max * 100, 1);&lt;br&gt;&lt;strong&gt;//パラメータ引き渡し型スレッドデリゲート&lt;/strong&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Thread th = new Thread(new ParameterizedThreadStart(Form2.ThreadMethod));&lt;br&gt;&lt;strong&gt;//パラメータ渡し&lt;br&gt;&lt;/strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; th.Start(param);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int i = progressBar1.Minimum; i &amp;lt;= progressBar1.Maximum; i++)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Thread.Sleep(1000);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; progressBar1.PerformStep();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; label1.Text = string.Format("{0:d4} 回目の処理を行いました", i);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Application.DoEvents();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;}  &lt;p&gt;ところが結果は同じで、メインの処理とほぼ同じスピードでしかメッセージの表示更新が行われません。なぜならメインフォームの処理が完了したかどうかを「parent.Invoke(new GetBool(parent.Done)) 」で検査しているからです。Invokeは操作対象となるコントロールが存在するスレッド上で指定されたメソッドデリゲートの呼び出しを行うため、操作対象のコントロールがロックされていればロックが解除されるまで待つことになるからです。このような場合はBeginInvoke非同期メソッド呼び出しを使うとメインスレッドに引きずられることなくスプラッシュ側のスレッド処理を継続して行うことが出来ます。  &lt;p&gt;private void DoWork()&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.Show();&lt;br&gt;&lt;strong&gt;//ステータスの確認を非同期で行う&lt;/strong&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IAsyncResult art = parent.BeginInvoke(new GetBool(parent.Done));  &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int i = 0; true; i++)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!this.Visible) break;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Thread.Sleep(10);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; progressBar1.PerformStep();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; label1.Text = string.Format("{0:d4} 回目の処理を行いました", i);&lt;br&gt;&lt;strong&gt;//ステータス確認のメソッド呼び出しは完了しているか？&lt;/strong&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (art.IsCompleted)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&lt;strong&gt;//ステータスの取得&lt;/strong&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ((bool)parent.EndInvoke(art)) break;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br&gt;&lt;strong&gt;//ステータスが完了でないなら再度ステータス確認を非同期で行う&lt;/strong&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; art = parent.BeginInvoke(new GetBool(parent.Done));&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Application.DoEvents();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; label1.Text = "メインフォームの処理が完了しました";&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.Update();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Thread.Sleep(1000);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; label1.Text = "スプラッシュフォームを閉じます";&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.Update();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Thread.Sleep(1000);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.Close();&lt;br&gt;}  &lt;p&gt;BeginInvokeメソッドはEndInvokeメソッドと対で使用します。BeginInvokeメソッドはデリゲートを非同期で呼び出す役目、そしてEndInvokeメソッドはメソッド呼び出しが完了した時点で呼び出したメソッドの戻り値を取得する役目があります。BeginInvokeメソッドの戻り値はIAsyncResult インタフェース型のオブジェクトとなります。IAsyncResult には4つのプロパティがあり、そのうちの一つであるIsCompletedを使ってメソッド呼び出しが完了しているかどうかを確認しています。完了しているならEndInvokeメソッドを使ってメインフォーム側から提供される状況ステータスを取得します（Form1.Done()メソッド）。  &lt;p&gt;C# Cookbook のChap 18.4 ～ 18.6 では、非同期でのメソッド呼び出しやコールバックの方法、IAsyncResultインタフェースの使い方について判りやすくシンプルなコードで解説が行われています。今回紹介したスプラッシュとは直接関係はないのですが Chap 18の最初の段階では、多くの書籍のサンプルコードで採用されているロックの方法の問題点を明らかにしており、解決方法としてMSDN Magazine Jan 2003 のJeffrey Richter 氏の記事を引用参照しています。余談となりますが、Jeffrey Richter 氏の CLR via C# のPart Ⅴ：CLR Facilities Chapter 23（p.589～）、Chapter 24 ではスレッドについて詳細な解説がされています。  &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;iframe style="width: 120px; height: 240px" marginheight="0" src="http://rcm-jp.amazon.co.jp/e/cm?t=jubeiprogramm-22&amp;amp;o=9&amp;amp;p=8&amp;amp;l=as1&amp;amp;asins=0735621632&amp;amp;fc1=000000&amp;amp;IS2=1&amp;amp;lt1=_blank&amp;amp;lc1=0000ff&amp;amp;bc1=000000&amp;amp;bg1=ffffff&amp;amp;f=ifr" frameborder="0" marginwidth="0" scrolling="no"&gt;&lt;/iframe&gt;&lt;iframe style="width: 120px; height: 240px" marginheight="0" src="http://rcm-jp.amazon.co.jp/e/cm?t=jubeiprogramm-22&amp;amp;o=9&amp;amp;p=8&amp;amp;l=as1&amp;amp;asins=0596100639&amp;amp;fc1=000000&amp;amp;IS2=1&amp;amp;lt1=_blank&amp;amp;lc1=0000ff&amp;amp;bc1=000000&amp;amp;bg1=ffffff&amp;amp;f=ifr" frameborder="0" marginwidth="0" scrolling="no"&gt;&lt;/iframe&gt;&lt;img src ="http://blogs.wankuma.com/jubei/aggbug/172653.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>十兵衛（諸農）</dc:creator><title>アルゴリズムの再利用</title><link>http://blogs.wankuma.com/jubei/archive/2009/05/09/172652.aspx</link><pubDate>Sat, 09 May 2009 07:03:00 GMT</pubDate><guid>http://blogs.wankuma.com/jubei/archive/2009/05/09/172652.aspx</guid><wfw:comment>http://blogs.wankuma.com/jubei/comments/172652.aspx</wfw:comment><comments>http://blogs.wankuma.com/jubei/archive/2009/05/09/172652.aspx#Feedback</comments><slash:comments>8</slash:comments><wfw:commentRss>http://blogs.wankuma.com/jubei/comments/commentRss/172652.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/jubei/services/trackbacks/172652.aspx</trackback:ping><description>&lt;p&gt;Genericsを使うと、タイプセーフなアルゴリズムの再利用が可能となります。  &lt;p&gt;例えばコレクションや配列を逆順にソートしたい場合を考えてみます。逆順ソートの対象が配列型であるなら、まず最初にArray.Sort()メソッドを呼び出しその後にArray.Reverse()メソッドを呼び出すことで簡単に実現できます。つまりICollectionインタフェースを実装しているクラスであるならコレクションアイテムを一時的に配列に出力し、その配列に対してSort→Reverseを行うことで逆順ソートを実現することが出来ると言うことです。  &lt;p&gt;static private U[] SortReverse&amp;lt;T, U&amp;gt;(T Collection)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; where T : ICollection&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; where U : IComparable&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; U[] val = new U[Collection.Count];&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Collection.CopyTo(val, 0);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Array.Sort(val);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Array.Reverse(val);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return val;&lt;br&gt;}  &lt;p&gt;Genericsメソッドではメソッドで使用する型パラメータを「&amp;lt;&amp;gt;」内で宣言します。ここでは二種類の型を宣言しています。Tは引数の型、Uは戻り値となる配列の要素の型です。メソッド宣言の後にwhereを使って型パラメータに制約を付与しています。メソッド引数となるT型パラメータにはICollectionインタフェースが実装されている必要があります。なぜならICollection.CopyTo()メソッドを使ってコレクションアイテムの要素を一次元配列に格納する必要があるからです。そしてもう一つのU型パラメータにはIComparableインタフェースが実装されている必要があります。これはArray.Sort()メソッドが要素アイテムを比較する際にIComparableインタフェースを呼び出すからです。  &lt;p&gt;このようにGenericsメソッドを準備することで逆順ソートというアルゴリズムを再利用することが可能となります。次のstCollection()メソッドではStringCollectionクラスを使って文字列リストを作成し逆順ソートを行っていますが、intArray()メソッドではint型の配列（int[]型）で数値配列を作成して、先ほどのStringCollectionを逆順ソートしたのと同じメソッドで逆順ソートを実現しています。  &lt;p&gt;static void stCollection()&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; StringCollection slist = new StringCollection();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; slist.Add("伊太利亜");&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; slist.Add("阿弗利加");&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; slist.Add("露西亜");&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; slist.Add("英吉利");&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; slist.Add("独逸");&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; slist.Add("白耳義");&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; slist.Add("伯剌西爾");&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; slist.Add("加奈陀");&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; slist.Add("仏蘭西");&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; slist.Add("日本");&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; slist.Add("亜米利加");&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; slist.Add("阿蘭陀");&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; slist.Add("印度");&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; slist.Add("濠太剌利");&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; string[] sAry = SortReverse&amp;lt;StringCollection, string&amp;gt;(slist);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; DispList&amp;lt;string[]&amp;gt;(sAry, "文字列の逆ソート");&lt;br&gt;}  &lt;p&gt;static void intArray()&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int[] iAry = new int[] { 5, 9, 12, 87, 3, 4, 8 };&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; iAry = SortReverse&amp;lt;int[], int&amp;gt;(iAry);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; DispList&amp;lt;int[]&amp;gt;(iAry, "数値の逆ソート");&lt;br&gt;}  &lt;p&gt;&lt;a href="http://jubei.wankuma.com/images/a8557c3becfd_634E/sortOrder000.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px" border="0" alt="sortOrder000" src="http://jubei.wankuma.com/images/a8557c3becfd_634E/sortOrder000_thumb.jpg" width="292" height="214"&gt;&lt;/a&gt;  &lt;p&gt;今回作成したメソッドを利用する上で注意が必要なのは、配列要素に自分で定義した型（クラス）を利用しようとした場合にIComparableインタフェースを実装する必要があるということです。もしも実装していない場合はコンパイル時にエラーとなります。これはメソッドの型パラメータに対してwhereキーワードで制約を付与しているからです。このように制約を与えることでGenericsの持つ「タイプセーフ」をより厳密にすることができます。  &lt;p&gt;例えば次のようなクラスを作成し、List&amp;lt;&amp;gt;クラスで保持した後に逆順ソートを行おうとしてもコンパイル時に次のようなエラーが出力されます。  &lt;p&gt;//IComparableを実装していないクラス&lt;br&gt;class MyClass&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private string fname;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private string lname;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public MyClass(string ALastName, string AFirstName)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fname = AFirstName;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; lname = ALastName;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public string FirstName&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return fname; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public string LastName&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return lname; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public override string ToString()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return string.Format("{0} , {1}", lname, fname);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;}&lt;br&gt;static void myTypeArray()&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; List&amp;lt;MyClass&amp;gt; myList = new List&amp;lt;MyClass&amp;gt;();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; myList.AddRange(&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new MyClass[]&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new MyClass("本上","まなみ"),&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new MyClass("宮部","みゆき"),&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new MyClass("黒谷","友香"),&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new MyClass("南野","陽子"),&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new MyClass("菅山","かおる")&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; );&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MyClass[] myAry = SortReverse&amp;lt;List&amp;lt;MyClass&amp;gt;, MyClass&amp;gt;(myList);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; DispList&amp;lt;MyClass[]&amp;gt;(myAry, "マイクラスの逆ソート");&lt;br&gt;}  &lt;p&gt;&lt;a href="http://jubei.wankuma.com/images/a8557c3becfd_634E/SortOrder001.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px" border="0" alt="SortOrder001" src="http://jubei.wankuma.com/images/a8557c3becfd_634E/SortOrder001_thumb.jpg" width="305" height="48"&gt;&lt;/a&gt;  &lt;p&gt;「型 'SortOrderC.Program.MyClass' は、ジェネリック型またはメソッド 'SortOrderC.Program.SortReverse&amp;lt;T,U&amp;gt;(T)' 内でパラメータ 'U' として使用するために、'System.IComparable' に変換可能でなければなりません。」&lt;br&gt;制約のせいでエラーが出るからといって制約を外してしまうと、実行時にArray.Sort()のところでエラーになるので、頑張ってIComparableを実装するようにしましょう。  &lt;p&gt;&lt;a href="http://jubei.wankuma.com/images/a8557c3becfd_634E/sortOrder002.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px" border="0" alt="sortOrder002" src="http://jubei.wankuma.com/images/a8557c3becfd_634E/sortOrder002_thumb.jpg" width="307" height="225"&gt;&lt;/a&gt;  &lt;p&gt;コンソール出力用のメソッドもGenericsメソッドを使用しています。ここでも同じようにwhereキーワードを使って制約を付与しています。  &lt;p&gt;static private void DispList&amp;lt;T&amp;gt;(T Collection, string AMessage)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; where T : IEnumerable&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(AMessage);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (object o in Collection)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine("Item value = {0}", o);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine("");&lt;br&gt;} &lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/jubei/aggbug/172652.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>十兵衛（諸農）</dc:creator><title>MSDN Library 2007 06 のインストール</title><link>http://blogs.wankuma.com/jubei/archive/2007/07/15/85241.aspx</link><pubDate>Sun, 15 Jul 2007 09:29:00 GMT</pubDate><guid>http://blogs.wankuma.com/jubei/archive/2007/07/15/85241.aspx</guid><wfw:comment>http://blogs.wankuma.com/jubei/comments/85241.aspx</wfw:comment><comments>http://blogs.wankuma.com/jubei/archive/2007/07/15/85241.aspx#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://blogs.wankuma.com/jubei/comments/commentRss/85241.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/jubei/services/trackbacks/85241.aspx</trackback:ping><description>&lt;p&gt;2007年6月号がアップされていたので、この休みを利用してインストールしてみようと思ったのですが。。。&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;a href="http://jubei.wankuma.com/images/MSDNLibrary200706_853B/MSDN200706_001.png" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="284" alt="MSDN200706_001" src="http://jubei.wankuma.com/images/MSDNLibrary200706_853B/MSDN200706_001_thumb.png" width="355" border="0"&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;なぜディスクが必要なの？？？&lt;br&gt;仕方がないのでキャンセルをクリック。&lt;/p&gt; &lt;p&gt;&lt;a href="http://jubei.wankuma.com/images/MSDNLibrary200706_853B/MSDN200706_002.png" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="271" alt="MSDN200706_002" src="http://jubei.wankuma.com/images/MSDNLibrary200706_853B/MSDN200706_002_thumb.png" width="349" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;取り消すしかないでしょう？&lt;br&gt;他に方法があるんなら良いんだけど。。&lt;/p&gt; &lt;p&gt;&lt;a href="http://jubei.wankuma.com/images/MSDNLibrary200706_853B/MSDN200706_003.png" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="270" alt="MSDN200706_003" src="http://jubei.wankuma.com/images/MSDNLibrary200706_853B/MSDN200706_003_thumb.png" width="348" border="0"&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;結局、インストールできずに終わってしまった。。。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/jubei/aggbug/85241.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>十兵衛（諸農）</dc:creator><title>MSDN Subscriber Downloads</title><link>http://blogs.wankuma.com/jubei/archive/2006/09/24/39500.aspx</link><pubDate>Sun, 24 Sep 2006 20:52:00 GMT</pubDate><guid>http://blogs.wankuma.com/jubei/archive/2006/09/24/39500.aspx</guid><wfw:comment>http://blogs.wankuma.com/jubei/comments/39500.aspx</wfw:comment><comments>http://blogs.wankuma.com/jubei/archive/2006/09/24/39500.aspx#Feedback</comments><slash:comments>40</slash:comments><wfw:commentRss>http://blogs.wankuma.com/jubei/comments/commentRss/39500.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/jubei/services/trackbacks/39500.aspx</trackback:ping><description>&lt;P&gt;サブスクライバダウンロードサイトに入るとトップページに「最新のダウンロード一覧」が表示されますね。ざっと目を通すとそこに「MSDN Subscriptions Library, September 2006 Edition - DVD (Japanese)」を発見したわけです。先日届いたものは8月版だったし、あれまぁもう更新されたんかいな、ってことで3時間ほど掛けてダウンロードしました。&lt;BR&gt;そしたら、中身は先日分と同じ8月版でしたとさ。。(T_T)&lt;/P&gt;
&lt;P&gt;気を取り直して、Vista RC1 Build5600 をダウンロードしてみようかと。&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;img src ="http://blogs.wankuma.com/jubei/aggbug/39500.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>十兵衛（諸農）</dc:creator><title>Turbo Delphi のネタ</title><link>http://blogs.wankuma.com/jubei/archive/2006/09/18/39011.aspx</link><pubDate>Mon, 18 Sep 2006 12:55:00 GMT</pubDate><guid>http://blogs.wankuma.com/jubei/archive/2006/09/18/39011.aspx</guid><wfw:comment>http://blogs.wankuma.com/jubei/comments/39011.aspx</wfw:comment><comments>http://blogs.wankuma.com/jubei/archive/2006/09/18/39011.aspx#Feedback</comments><slash:comments>18</slash:comments><wfw:commentRss>http://blogs.wankuma.com/jubei/comments/commentRss/39011.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/jubei/services/trackbacks/39011.aspx</trackback:ping><description>&lt;P&gt;Turbo Delphi Explorer のネタをココログにアップしました。&lt;/P&gt;
&lt;P&gt;&lt;A href="http://programmers-jubei.cocolog-nifty.com/blog/2006/09/turbo_delphi_ex_2111.html"&gt;Turbo Delphi Explorer にコンポを登録&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="http://programmers-jubei.cocolog-nifty.com/blog/2006/09/turbo_delphi_ex_4f30.html"&gt;Turbo Delphi Explorer で実行時パッケージを使う&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;画像がたくさんなのでココログへ。。(^^;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;編集追記&lt;BR&gt;最初の投稿記事では裏技によるコンポの登録方法を知るリンクを貼り付けていましたが削除いたしました。また、スナップショットも削除いたしました。&lt;BR&gt;ライセンス違反を助長する投稿をしましたことを深くお詫びいたします。&lt;/STRONG&gt;&lt;STRONG&gt;&lt;BR&gt;とおりすがりさんによるコメント・助言、ありがとうございました。&lt;/STRONG&gt;&lt;/P&gt;&lt;img src ="http://blogs.wankuma.com/jubei/aggbug/39011.aspx" width = "1" height = "1" /&gt;</description></item></channel></rss>