<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>kyoh.net</title>
	<atom:link href="http://kyoh.net/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://kyoh.net</link>
	<description>Would you take a cup of coffee?</description>
	<lastBuildDate>Sun, 13 Jun 2010 01:03:41 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>プログラミングにおけるエディタのフォント</title>
		<link>http://kyoh.net/?p=268</link>
		<comments>http://kyoh.net/?p=268#comments</comments>
		<pubDate>Sun, 13 Jun 2010 01:03:41 +0000</pubDate>
		<dc:creator>kyoh</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[エディタ]]></category>
		<category><![CDATA[フォント]]></category>
		<category><![CDATA[プログラミング]]></category>

		<guid isPermaLink="false">http://kyoh.net/?p=268</guid>
		<description><![CDATA[見やすいエディタのフォント、と言うことでこだわりのエディタチョイスがいろいろなブログでエントリーされていますが。
Osaka-等幅にしろ、M+ + IPAにしろ、漢字が潰れない　という最低限の条件が満たせていないので、お [...]]]></description>
			<content:encoded><![CDATA[<p>見やすいエディタのフォント、と言うことでこだわりのエディタチョイスがいろいろなブログでエントリーされていますが。<br />
Osaka-等幅にしろ、M+ + IPAにしろ、漢字が潰れない　という最低限の条件が満たせていないので、お話になりません。Osaka-等幅の9ptはビットマップで見やすいよ！などと書いてあったりはしますが、Oと0など紛らわしい文字については同意できるものの、それ以外の文字が見やすいとはお世辞にも言い難い。同じ9ptの割には小さすぎるし、漢字は潰れるし。<br />
Windows 7環境なのが悪いのかしら。</p>
<p>結局、MSゴシック＋9ポイントを使い続けるハメになるのです。MSゴシックが、スラッシュドゼロとか、lとIと1の見分け付けたりしてくれればそれで万事解決なのですがね。</p>
<p>メイリオ-等幅、なんて公式で出ないかなあ。</p>
]]></content:encoded>
			<wfw:commentRss>http://kyoh.net/?feed=rss2&amp;p=268</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OOPについて考える</title>
		<link>http://kyoh.net/?p=263</link>
		<comments>http://kyoh.net/?p=263#comments</comments>
		<pubDate>Sat, 22 May 2010 14:36:53 +0000</pubDate>
		<dc:creator>kyoh</dc:creator>
				<category><![CDATA[Meta]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[オブジェクト指向]]></category>

		<guid isPermaLink="false">http://kyoh.net/?p=263</guid>
		<description><![CDATA[OOP（オブジェクト指向プログラミング・Object Oriented Programing）とは一体なんぞや、という話を方法論ではなく、もと根本の「なぜOOPなのか」という視点から眺めてみました。
ただ、私はOOPの価 [...]]]></description>
			<content:encoded><![CDATA[<p>OOP（オブジェクト指向プログラミング・Object Oriented Programing）とは一体なんぞや、という話を方法論ではなく、もと根本の「なぜOOPなのか」という視点から眺めてみました。<br />
ただ、私はOOPの価値を「カプセル化」にこそあると考えているため、その一点に絞った記事となっています。他の部分については、殆ど言及されていない代物ですので、ご注意ください。<span id="more-263"></span></p>
<h3>OOPに対する拒絶反応</h3>
<p>これまで、Web上でいろいろなOOPに関する書き物を目にしました。そして、その書き物に対する、様々な意見にも、極力目を通すよう心がけてきました。<br />
その中によくある「OOPって難しい」「必要性が分からない」といったような、OOPに対する拒絶反応を見てきて、少々残念に思うことがあります。</p>
<h3>「難しく考えさせすぎ」</h3>
<p>OOPを勉強しようと思い立った時、Webにせよ専門書にせよ、OOPについて書かれたものを開くことになるでしょう。しかし、それらを開いてぱっと目につくのは「多態性が云々」「カプセル化が云々」と、「OOPを実現するための要件」ばかりに思えます。</p>
<p>－そりゃあ無理ですよ。いきなりわかりもしない言葉を並び立てて、難しく考えさせすぎというものです。</p>
<h3>私がOOPに至るまで</h3>
<p>私自身は幸いにして、高専という恵まれた環境下で、授業やその他様々なシーンにおいて、プログラミング（や、その周辺知識）を勉強してきました。<br />
その中で、自分なりにどういう風にプログラミングすれば「デバッグしやすく」「人にも読みやすく」「次回の授業につなげられる」プログラムが書けるのか、という工夫をしてきました。</p>
<p>紆余曲折はあったものの結果として、当時の私はC言語しか使えなかったものの、「なんとなくオブジェクト指向的」なプログラムを無意識に書いていた覚えがあります。<br />
そういう背景や基盤があったからこそ、先に挙げた様な書き物を読んで、荒唐無稽なオブジェクト指向の方法論を突きつけられても、ある程度の苦労はあっても理解できた、と思います。</p>
<h3>OOPの現状と未来</h3>
<p>今改めて、世にある「OOP入門」といえるものを読み返してみると、理解したつもりになっていても難しく感じます。これでは尚のこと、「オブジェクト指向なんてどうでもいいや」と思っていたり、あるいは「知りたいけど何もわからない」と思っていたりする人たちにとっては、それこそ苦痛以外の何ものでもない代物となってしまっても不思議はありません。「分かっている奴だけ使えばいいじゃない」となっても仕方のないことだと思います。<br />
理解して推してくる人間－こと、信者と言えるような熱心な人たち－が疎ましく思えてしまうのも無理はありません。</p>
<p>私はこの状況が好ましいものだとは思えません。なぜならば、OOPは何ら難しいものでも、不愉快なものでもなく、ずっと素直で簡潔なものだと考えているからです。<br />
そして、それはもっと多くの人に理解され、そして肯定も（拒絶ではなく）否定も含めた議論がもっと成されるべきだと考えているのです。</p>
<h3>この記事の動機</h3>
<p>そのためには、もう少し「なぜ、OOPなのか」あるいは「OOPが目標とするところは何なのか」を、抽象的に論じた話が、さわりとしてあった方がいいように思います。「OOP概論」のような。</p>
<h3>OOPってなんぞや</h3>
<p>OOPって何ですか、って話は、某高専の情報系学科、入学直後の「情報工学概論」という授業で最初に教授が切り出した話題に答えがあるように思います。</p>
<p>「“情報”とはなんですか」</p>
<p>曰く、「情報＝データ＋意味」なんだそうです。<br />
これは決してその教授が考えた、という話ではなく、工学的に見た「情報」とはなんぞや、という一般論です。当時は、こいつは一体何を言い出すのだ、と思っていましたが（ごめんなさい、S先生）、今思えば確かになあ、と納得できる話です。<br />
あくまでも工学的な理屈の上での、「情報とは」なんですけれど。</p>
<h3>情報とオブジェクト</h3>
<p>情報とは、データ＋意味である。<br />
では、データとは何か。<br />
究極的にいえば（コンピュータ上では）0と1のあつまりだ。<br />
では、意味とは何か。<br />
それが「画像」であるのか、「文章」であるのか、「音声」であるのか・・・つまるところ、「データをどう処理するか」というデータに対するメタだ。</p>
<p>では、情報とはどうあるべきか。<br />
データ＋意味であるべきだ。</p>
<p>データが意味を喪失したとき、それは情報ではない。単なる値の集合体だ。<br />
そして悲しき哉、データそのものに何ら「意味」はない。</p>
<p>逆に、「意味」だけがあってもしかたない。<br />
意味があっても、データが無ければ、情報の体は成さず、データが間違っていれば、情報自体が誤りとなり、これもまた「意味」がない。</p>
<p>データと意味・・・つまり、そのデータをどう「処理するか」ということは、常にセットであってほしいものなのです。</p>
<h3>プログラミングと「情報」</h3>
<p>さて。<br />
プログラミングとは、「情報処理」の塊です。<br />
実際に処理をするのは、コンピュータ側ですが、それを命じるのは人間です。情報処理を命じるのは一般的にはプログラミングのソースコードです。そしてそのソースコード上にもまた、数多くの情報があふれています。これを人間が読み解くとき、「データ」と「意味（処理）」が離れていては、それを情報としてみなすことが難しくなってしまいます。</p>
<p>可能な限り、データと意味、両者は近くにあってほしいのです。ならばどうするか。</p>
<p>・・・</p>
<h3>抽象的な話</h3>
<p>「データ」と紐づく｢意味（処理）」は、共通の箱にしまいましょう。<br />
そして、必ず箱単位で扱うようにしましょう。<br />
めったなことで、外から箱の中身をのぞいてはいけません。ましてや、中のデータを勝手に書き換えたりしてしまっては、箱の「意味」はなくなってしまいます。</p>
<p>箱の種類が増えてきて、またいくつかの箱で「意味」が形成されたなら、その箱たちをより大きな箱にしまいましょう。やっぱりその箱も、外から覗いたり、データだけ書き換えたりしてはいけません。中身の箱だけ勝手に入れ替えるのもいけません。「意味」を成さなくなってしまいます。</p>
<p>・・・</p>
<h3>OOPとそのメリット</h3>
<p>ソースコード上といえども、情報はあくまで一つの「情報」として扱い、どこからどこまでが「一つの情報」なのかを明確にするべきです。<br />
そうすることで、人がソースコードを見た時に、「ここでこういうデータにこういう処理をしている、はたしてそれは情報として正しいか？」ということを判断するだけで済むようになります。<br />
そして、「情報」という単位が明確に定められていれば、その情報に対して人間が行う作業も、明確な範囲をもって行うことが可能になるでしょう。<br />
たとえばそこに新しい意味（価値）を付加することも、あるいは後から「意味」を変えることも、対象となる「情報」の枠の外にでることなく実行することが可能です。</p>
<h3>おわりに</h3>
<p>これまでぐだぐだと書いてきましたが、これらはあくまで理想論の上でのOOPについて論じたものです。実際には、開発する言語や環境、要件や既存資源などによって数多くの制約を受けることになります。<br />
結果として、中途半端なOOPは皆の頭を悩ませる代物を生み出すおそれもあります。</p>
<p>それでも、一人でも多くの人がOOPを深く理解し、結果、世に溢れた中途半端なOOPが少しでも完成度の高いものに近づけるなら、と思い、この様な記事を書いた次第です。<br />
この記事を読んで、そうか、OOPも意外とシンプルな話なのかもしれんと、おもってくれる一人でもいたなら、それはとてもうれしいことです。</p>
]]></content:encoded>
			<wfw:commentRss>http://kyoh.net/?feed=rss2&amp;p=263</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Twitterクライアント（いまさら？）</title>
		<link>http://kyoh.net/?p=260</link>
		<comments>http://kyoh.net/?p=260#comments</comments>
		<pubDate>Fri, 14 May 2010 08:38:42 +0000</pubDate>
		<dc:creator>kyoh</dc:creator>
				<category><![CDATA[memo]]></category>

		<guid isPermaLink="false">http://kyoh.net/?p=260</guid>
		<description><![CDATA[twitter文言解析/文言作成
@～機能の充実を見込む。拡張性を重んじる
・twitterにあるものは、如何なる場合も究極的に140文字の文字列である。
　⇒あくまでもシリアル化されたデータの中に、さまざまな構造を持つ [...]]]></description>
			<content:encoded><![CDATA[<p>twitter文言解析/文言作成<br />
@～機能の充実を見込む。拡張性を重んじる</p>
<p>・twitterにあるものは、如何なる場合も究極的に140文字の文字列である。<br />
　⇒あくまでもシリアル化されたデータの中に、さまざまな構造を持つ。<br />
・構造は時とともに変貌し、そしてそれをサポートすることは一定のニーズを見込む。</p>
<p>・言語構造とは・・・？</p>
<p>・構造が持つ機能と、その構造のシリアル化された姿の対応<br />
　⇒まさしくクラス。以下構造をクラスと呼ぶ。</p>
<p>・シリアル化されたデータに対して、各クラスが出来ることは、<br />
　「クラス自身にとって関心のある部分と、そうでない部分（文字列）との分割」</p>
<p>・ならばTweet全体は常に、単なる文字列と各種クラスがシリアルに並ぶ構造＝クラスである。</p>
<p>・構造の例<br />
　以下で大文字はクラスの識別子、小文字は変数的なもの。<br />
　「******」で記述される部分は、クラスが関心を持たない部分。<br />
　「～～～」で記述される部分は、クラスが関心を持つ部分。</p>
<p>・・前置（例: ReTweet）<br />
　　******@RT～～～～～～</p>
<p>・・後置（例: RESponce）<br />
　　～～～～～～@id******</p>
<p>・・包括（現状存在しないので、飽くまで例: PaンチのあるTsuぶやき。PunchTweet）<br />
　　******@PT{～～～@PT}******<br />
　　（もう一例: URLリンクTweet。Uniqlo T-shirts）<br />
　　******@UT{～～～ | http://？？？@UT}******</p>
<p>各クラス内部についてはシリアル化の限りではなく、包括関係や上下関係を伴う可能性もある。</p>
<p>　　******@RT～～～@PT{？？？@PT}～～～<br />
　構造例：（ただし、以下の例においてSTRとは単なる文字列を示すための便宜上の識別子である）<br />
　　******　＝　～～～　＝　？？？　＝　～～～</p>
<p>　⇒ROOT {{<br />
　　　STR {{ ****** }}<br />
　　　RT  {{<br />
　　　　STR {{ ～～～ }}<br />
　　　　PT　{{ ？？？ }}<br />
　　　　STR {{ ～～～ }}<br />
　　　}}<br />
　　}}</p>
<p>・単一のクラスが、単一の構造を持つとは限らない。<br />
　例：<br />
　　@PT～～～～～～、または～～～～～～@PTとした場合、<br />
　　Tweet全体がPunchなのだ。</p>
<p>・PT、RTその他は拡張により、その定義を外部から与えることができる　⇒参照: MEF</p>
<p>・構造化する構文は、複雑すぎれば意図的な使用者に混乱を招く。<br />
　単純すぎれば意図しない使用による混乱を招く。</p>
<p>・クラスのインターフェース (仮り名: [TW]</p>
<p>　・readonly char 識別子;　 #「P」⇒「@PT」みたいな。どんと来い混乱。<br />
　・TW[] 解析( 文字列 );　　# 上位のクラスから呼ばれる。</p>
<p>・ルートクラス</p>
<p>　・プラグインの読み込み、<br />
　・文字列を各プラグインに噛ませて読ませる。</p>
]]></content:encoded>
			<wfw:commentRss>http://kyoh.net/?feed=rss2&amp;p=260</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Internet Explorerにおけるシングルラインテキストボックスのバグ</title>
		<link>http://kyoh.net/?p=240</link>
		<comments>http://kyoh.net/?p=240#comments</comments>
		<pubDate>Fri, 14 May 2010 02:45:02 +0000</pubDate>
		<dc:creator>kyoh</dc:creator>
				<category><![CDATA[Tips]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[バグ]]></category>

		<guid isPermaLink="false">http://kyoh.net/?p=240</guid>
		<description><![CDATA[些細なことでも、書けばどこかで誰かに拾われるのがWebです。
Internet Explorerで、シングルラインテキストボックス（input type=&#8221;text&#8221;）にmaxlengthを設定し [...]]]></description>
			<content:encoded><![CDATA[<p>些細なことでも、書けばどこかで誰かに拾われるのがWebです。</p>
<p>Internet Explorerで、シングルラインテキストボックス（input type=&#8221;text&#8221;）にmaxlengthを設定しない場合、<br />
入力文字数が4,000を超えた時点で挙動が不正な状態になります。</p>
<p><span id="more-240"></span></p>
<h3>再現手順</h3>
<ul>
<li><c>&lt;input type=&#8221;text&#8221;&gt;</c>のように、最大長(maxlength)を指定しないシングルラインテキストボックスを作成する</li>
<li>ascii文字またはそれ以外の文字で、4,000文字入力する。ただし、両者を混成しない。<br />
　（あああああ、のように日本語文字で入力するなら、「a」などのアスキー文字を途中にまぜない。<br />
　　逆に、aaaaa、のようにascii文字で入力するなら、「あ」などのその他のの文字を途中にまぜない。）</li>
</ul>
<h3>現象</h3>
<p>
4,000文字を超えた時点で、入力された文字の表示がおかしくなります。<br />
入力できることはできますが、入力直後は表示されず（空白が入力されているように見える）、選択などによってあらためて再表示をかけると、その時点で表示される、という挙動をとります。<br />
実際にこの状態で送信した場合、どのような挙動になるかは未確認です。
</p>
<h3>環境</h3>
<p>現象は、IE8、IE8互換表示モードで確認されています。その他のIEについては未検証です。</p>
<h3>対策</h3>
<p>maxlengthをかならず4,000文字以下で設定します。4,000文字以上の入力が必要となるケースは、textboxやファイルのアップロードで対応します。</p>
]]></content:encoded>
			<wfw:commentRss>http://kyoh.net/?feed=rss2&amp;p=240</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C# 4.0 / .NET Framework 4 / Visual Studio 2010雑感</title>
		<link>http://kyoh.net/?p=214</link>
		<comments>http://kyoh.net/?p=214#comments</comments>
		<pubDate>Wed, 12 May 2010 06:04:08 +0000</pubDate>
		<dc:creator>kyoh</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://kyoh.net/?p=214</guid>
		<description><![CDATA[（Visual Studio 2010 Express）
まず重い。低スペックパソコンでは、ストレスない開発など不可能。
Celeron 2.0GHz + 1.97GB RAM、グラボなし環境下では、XAMLデザイナがち [...]]]></description>
			<content:encoded><![CDATA[<h3>（Visual Studio 2010 Express）</h3>
<p style="padding-left: 30px;">まず重い。低スペックパソコンでは、ストレスない開発など不可能。<br />
Celeron 2.0GHz + 1.97GB RAM、グラボなし環境下では、XAMLデザイナがちょくちょくフリーズする。あるいは画面が乱れて、現状が見えなくなる。<br />
Core i7 + 6.0GB RAM、Radeon環境下でも、時々表示が狂う。バグか？</p>
<p style="padding-left: 30px;">Intellisenseに至っては、エディタのリアルタイム描画を邪魔する始末。<br />
記述中にIntelilsenseが開いていると、記述中の文字列が見えない。</p>
<h3>.NET Framework 4.0 / C#</h3>
<p style="padding-left: 30px;">なんで<c>Path</c>ってクラスを増やした・・・！<br />
なんだかんだファイルシステムを扱う機会は多いので、そのたびに<c>System.IO.Path</c>と<c>System.Windows.Shapes.Path</c> が衝突を起こして、<c>System.IO.Path</c>と書く必要が生じる。</p>
<p style="padding-left: 30px;">名づけ参照（だっけ？　「<c>using IOPath = System.IO.Path</c>」みたいな）をすればいいんでしょうけど、そんな馬鹿なことって。<br />
<c>System.IO.Path</c>自体は、<c>Path.Combine(params string[] </c>～なんてのが増えてたりして、ありがたい。<br />
というか、全体的に<acronym>Linq</acronym>重視のメソッド増強・メンバ増強が成されてて嬉しいところが多い。<c>String.Join</c>なんかも、<br />
<a href="http://msdn.microsoft.com/ja-jp/library/dd783876.aspx">String.Join メソッド (String, IEnumerable(String)) (System) &#8211; MSDN ライブラリ</a><br />
こんな風に増強されてて、今まで<c>IEnumerable&lt;T&gt;.Cast()</c>だの<c>IEnumerable&lt;T&gt;.ToArray()</c>だのを頻発していた部分が、よりスマートに書けるようになっている。<br />
<c>String.IsNullOrWhiteSpace()</c> など、基本的なクラスにさりげない増強が施されているので、調査続行の予定。</p>
<p style="padding-left: 30px;">進化した結果、使い勝手は落ちている部分がいくらかある。<br />
いつだって進化に犠牲はつきもの・・・が、<c>System.IO.Path</c> &lt;-&gt; <c>System.Windows.Shapes.Path</c> だけはどうにかならなかったものか。</p>
<h3>その他の新機能覚書</h3>
<ul>
<li><a href="http://msdn.microsoft.com/ja-jp/library/ms171868(v=VS.100).aspx#core_new_features_and_improvements">.NET Framework 4 の新機能</a></li>
<li><a href="http://msdn.microsoft.com/ja-jp/library/system.text.stringbuilder.clear(v=VS.100).aspx">StringBuilder.Clear メソッド</a></li>
<li><a href="http://msdn.microsoft.com/ja-jp/library/system.diagnostics.stopwatch.restart(v=VS.100).aspx">Stopwatch.Restart メソッド</a></li>
<li><a href="http://msdn.microsoft.com/ja-jp/library/system.enum.tryparse(v=VS.100).aspx">Enum.TryParse メソッド</a></li>
<li><a href="http://msdn.microsoft.com/ja-jp/library/system.environment.specialfolder(v=VS.100).aspx">Environment.SpecialFolder 列挙体</a></li>
<li><a href="http://msdn.microsoft.com/ja-jp/library/system.io.path.combine(v=VS.100).aspx">Path.Combine メソッド</a></li>
<li><a href="http://msdn.microsoft.com/ja-jp/library/dd412070(v=VS.100).aspx">SortedSet&lt;T&gt; クラス</a></li>
<li><a href="http://msdn.microsoft.com/ja-jp/library/system.string.isnullorwhitespace(v=VS.100).aspx">String.IsNullOrWhiteSpace メソッド</a></li>
<li><a href="http://msdn.microsoft.com/ja-jp/library/system.string.concat(v=VS.100).aspx">String.Concat メソッド</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://kyoh.net/?feed=rss2&amp;p=214</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Linq (Linq to object) にもう半歩踏み込んでみる</title>
		<link>http://kyoh.net/?p=210</link>
		<comments>http://kyoh.net/?p=210#comments</comments>
		<pubDate>Mon, 19 Apr 2010 07:41:21 +0000</pubDate>
		<dc:creator>kyoh</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Linq to object]]></category>
		<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://kyoh.net/?p=210</guid>
		<description><![CDATA[Linq (Linq to object) はとても便利なものです。
今までいちいちforeach (or for, while, do &#8211; while) を使って、予備の変数を用意して、云々・・・とやってい [...]]]></description>
			<content:encoded><![CDATA[<p>Linq (Linq to object) はとても便利なものです。<br />
今までいちいちforeach (or for, while, do &#8211; while) を使って、予備の変数を用意して、云々・・・とやっていた処理が、<br />
（一部とはいえ）一行の式と、メソッド呼び出しで書けてしまう。<br />
実にクール。<br />
ですが、これを使うに当たっては、注意しなくてはならないこともあります。</p>
<p><strong>「効率」</strong></p>
<p>効率はいつだって（結論に差はあれ）考えなくてはならないことで、それを無視してコーディングするようでは、どんなに便利な道具でも時に凶器と化すように、Linq もまた単なる「お荷物」になりかねません。せっかくの便利な道具を、お荷物にしてしまわないためには、その内部をある程度知っておく必要があるでしょう。逆に、Linqを便利で、かつ効率の良いツールとして活用するためにも、それは必須のことと思います。</p>
<p>かといって、私はLinqの中身をILで・・・とか、そんなことは考えるのも億劫なので、「実際に動かして結果を見てみればいいじゃない！」という手抜き工程を踏みます。ゆえに、「一歩」の踏み込みには及ばずながらも、「半歩」程度は踏み込めてるかなあ、と。</p>
<p>さて、サンプルコードです。</p>
<pre class="brush: csharp;">using System;
using System.Collections.Generic;
using System.Linq;

namespace Kyoh.Tips.LinqExtensions
{
	static class Program
	{
		static void Main(string[] args)
		{
			var enum1 = enumTest(&quot;enum1&quot;, 1, 5);
			var enum2 = enumTest(&quot;enum2&quot;, 3, 7);
			var enum3 = enumTest(&quot;enum3&quot;, 2, 3);

			Console.WriteLine(&quot;Aggregate:&quot;);
			enum1.Aggregate((x, y) =&gt; x);
			Console.WriteLine();

			Console.WriteLine(&quot;All:&quot;);
			enum1.All(x =&gt; x != 3);
			Console.WriteLine();

			Console.WriteLine(&quot;Any:&quot;);
			enum1.Any(x =&gt; x == 3);
			Console.WriteLine();

			Console.WriteLine(&quot;AsEnumerable.run:&quot;);
			enum1.AsEnumerable().Run();
			Console.WriteLine();

			Console.WriteLine(&quot;AsQueryable.run:&quot;);
			enum1.AsQueryable().Run();
			Console.WriteLine();

			Console.WriteLine(&quot;Average:&quot;);
			enum1.Average();
			Console.WriteLine();

			Console.WriteLine(&quot;Concat.run:&quot;);
			enum1.Concat(enum2).Run();
			Console.WriteLine();

			Console.WriteLine(&quot;Contains(3):&quot;);
			enum1.Contains(3);
			Console.WriteLine();

			Console.WriteLine(&quot;Count:&quot;);
			enum1.Count();
			Console.WriteLine();

			Console.WriteLine(&quot;Distinct.run:&quot;);
			enum1.Distinct().Run();
			Console.WriteLine();

			Console.WriteLine(&quot;ElementAt(3):&quot;);
			enum1.ElementAt(3);
			Console.WriteLine();

			Console.WriteLine(&quot;ElementAtOrDefault(-1):&quot;);
			enum1.ElementAtOrDefault(-1);
			Console.WriteLine();

			Console.WriteLine(&quot;Except.run:&quot;);
			enum1.Except(enum3).Run();
			Console.WriteLine();

			Console.WriteLine(&quot;First:&quot;);
			enum1.First(i =&gt; i == 3);
			Console.WriteLine();

			Console.WriteLine(&quot;Intersect.run:&quot;);
			enum1.Intersect(enum2).Run();
			Console.WriteLine();

			Console.WriteLine(&quot;Last:&quot;);
			enum1.Last(i =&gt; i == 3);
			Console.WriteLine();

			Console.WriteLine(&quot;LastOrDefault:&quot;);
			enum1.LastOrDefault(i =&gt; i == 3);
			Console.WriteLine();

			Console.WriteLine(&quot;Max:&quot;);
			enum1.Max();
			Console.WriteLine();

			Console.WriteLine(&quot;OrderBy:&quot;);
			enum1.OrderBy(i =&gt; i);
			Console.WriteLine();

			Console.WriteLine(&quot;Reverse.run:&quot;);
			enum1.Reverse().Run();
			Console.WriteLine();

			Console.WriteLine(&quot;SequenceEqual:&quot;);
			enum1.SequenceEqual(enum3);
			Console.WriteLine();

			Console.WriteLine(&quot;Single:&quot;);
			enum1.Single(i =&gt; i == 3);
			Console.WriteLine();

			Console.WriteLine(&quot;SingleOrDefault:&quot;);
			enum1.SingleOrDefault(i =&gt; i == 3);
			Console.WriteLine();

			Console.WriteLine(&quot;Skip(3).run:&quot;);
			enum1.Skip(3).Run();
			Console.WriteLine();

			Console.WriteLine(&quot;Sum:&quot;);
			enum1.Sum();
			Console.WriteLine();

			Console.WriteLine(&quot;Take(3).run:&quot;);
			enum1.Take(3).Run();
			Console.WriteLine();

			Console.WriteLine(&quot;ToArray:&quot;);
			enum1.ToArray();
			Console.WriteLine();

			Console.WriteLine(&quot;ToDictionary:&quot;);
			enum1.ToDictionary(i =&gt; i);
			Console.WriteLine();

			Console.WriteLine(&quot;ToList:&quot;);
			enum1.ToList();
			Console.WriteLine();

			Console.WriteLine(&quot;ToLookup:&quot;);
			enum1.ToLookup(i =&gt; i % 2);
			Console.WriteLine();

			Console.WriteLine(&quot;Union.run:&quot;);
			enum1.Union(enum2).Run();
			Console.WriteLine();

			Console.WriteLine(&quot;Where.run:&quot;);
			enum1.Where(i =&gt; i != 3).Run();
		}

		public static void Run&lt;T&gt;(this IEnumerable&lt;T&gt; enumerable)
		{
			foreach (var item in enumerable)
				Console.WriteLine(&quot;      (running)&quot;);
		}
		static void empty() { }

		static IEnumerable&lt;int&gt; enumTest(string key, int min, int max)
		{
			try
			{
				Console.WriteLine(&quot;  start(&quot; + key + &quot;)&quot;);
				for (int i = min; i &lt;= max; i++)
				{
					Console.WriteLine(&quot;    &quot; + i.ToString());
					yield return i;
				}
			}
			finally { Console.WriteLine(&quot;  final(&quot; + key + &quot;)&quot;); }
		}
	}
}</pre>
<p>結論はここには書きませんが、実際にこれを動かしてみると、「思っていたのと違う！」というのもあるのではないでしょうか。<br />
今後Linqを使う場合に、これがひとつ「効率」の問題に何か投じることができれば、それはとても嬉しいことです。</p>
]]></content:encoded>
			<wfw:commentRss>http://kyoh.net/?feed=rss2&amp;p=210</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>XML ドキュメント コメント のカスタマイズ</title>
		<link>http://kyoh.net/?p=207</link>
		<comments>http://kyoh.net/?p=207#comments</comments>
		<pubDate>Tue, 13 Apr 2010 07:37:48 +0000</pubDate>
		<dc:creator>kyoh</dc:creator>
				<category><![CDATA[memo]]></category>
		<category><![CDATA[MSDN]]></category>
		<category><![CDATA[Visual Studio]]></category>
		<category><![CDATA[XMLドキュメントコメント]]></category>

		<guid isPermaLink="false">http://kyoh.net/?p=207</guid>
		<description><![CDATA[Documenting Your Code With XML Comments
自分で適当なタグを打ち込んでいいんだよ、っていう話だったけど、
Intellisense に表示してもらえなきゃ使いづらくてしょうがないだろ [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://msdn.microsoft.com/en-us/magazine/dd722812.aspx">Documenting Your Code With XML Comments</a><br />
自分で適当なタグを打ち込んでいいんだよ、っていう話だったけど、<br />
Intellisense に表示してもらえなきゃ使いづらくてしょうがないだろ、っていう話について、<br />
カスタマイズ方法がなかなか見つからなかったが、こんなところにあった・・・。</p>
<p>どうでもいいっちゃいいんですが、MSDN はもっとPerm linkについて真剣に考えるべき。<br />
最近大幅な改修があったみたいで、どこのサイトもリンクが切れてて非常に不愉快。</p>
]]></content:encoded>
			<wfw:commentRss>http://kyoh.net/?feed=rss2&amp;p=207</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>NetUse</title>
		<link>http://kyoh.net/?p=200</link>
		<comments>http://kyoh.net/?p=200#comments</comments>
		<pubDate>Thu, 08 Apr 2010 15:29:08 +0000</pubDate>
		<dc:creator>kyoh</dc:creator>
				<category><![CDATA[Softwares]]></category>

		<guid isPermaLink="false">http://kyoh.net/?p=200</guid>
		<description><![CDATA[一旦上げるだけ上げる。
詳細は後回し。
NetUseSetup_x86
NetUseSetup_x64
]]></description>
			<content:encoded><![CDATA[<p>一旦上げるだけ上げる。<br />
詳細は後回し。</p>
<p><a href='http://kyoh.net/wp-content/uploads/NetUseSetup_x86.zip'>NetUseSetup_x86</a><br />
<a href='http://kyoh.net/wp-content/uploads/NetUseSetup_x64.zip'>NetUseSetup_x64</a></p>
]]></content:encoded>
			<wfw:commentRss>http://kyoh.net/?feed=rss2&amp;p=200</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>二重起動の禁止と、コマンドライン引数などの受け渡し</title>
		<link>http://kyoh.net/?p=194</link>
		<comments>http://kyoh.net/?p=194#comments</comments>
		<pubDate>Tue, 06 Apr 2010 13:53:13 +0000</pubDate>
		<dc:creator>kyoh</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[IPC]]></category>
		<category><![CDATA[アクティブ化]]></category>
		<category><![CDATA[ウインドウ]]></category>
		<category><![CDATA[コマンドライン引数]]></category>
		<category><![CDATA[プロセス間通信]]></category>
		<category><![CDATA[二重起動]]></category>

		<guid isPermaLink="false">http://kyoh.net/?p=194</guid>
		<description><![CDATA[二重起動を禁止する、っていうエントリーは、いろんなところで見かけるんだけど、
二重起動を禁止して、尚かつ既に起動しているプロセスに対して何かする、っていうエントリーは、いまいち回答が見つかりにくい。
ならいっそ、共通処理化出来たら意外とニーズはあるんじゃないのか？という企み。]]></description>
			<content:encoded><![CDATA[<p>実に1年ぶりですね。あんまり書くネタないんだよな。調べれば大抵のことは他の人が書いてるし。</p>
<p>二重起動を禁止する、っていうエントリーは、いろんなところで見かけるんだけど、<br />
二重起動を禁止して、尚かつ既に起動しているプロセスに対して何かする、っていうエントリーは、いまいち回答が見つかりにくい。<br />
ならいっそ、共通処理化出来たら意外とニーズはあるんじゃないのか？という企み。</p>
<p>キーワードは、「Ipc」である。ここに書いてあることで理解できないことや、もっと発展的にやってみたい、という方は、「Ipc C#（またはVB）」で検索すれば、結構それなりに引っかかる。</p>
<p>まあ、ともあれ、まずはクラスのソースコードから。<br />
まず肝となる「ExtendetMutex」クラスから。本来の「Mutex」が意味するところとは若干違う役割を持っているけど、適切なクラス名が思いつかなかったので、最初につけた名前でずるずるときてしまっている。ご容赦。</p>
<pre class="brush: csharp;">
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Ipc;
using System.Runtime.Serialization.Formatters;
using System.Threading;

namespace ExMutex
{
	using BinaryClient = BinaryClientFormatterSinkProvider;
	using BinaryServer = BinaryServerFormatterSinkProvider;

	/// &lt;summary&gt;同プロセスが呼び出されたことを通知するデリゲート&lt;/summary&gt;
	/// &lt;typeparam name=&quot;TMessage&quot;&gt;通知するメッセージの型&lt;/typeparam&gt;
	/// &lt;param name=&quot;holder&quot;&gt;通知するメッセージ&lt;/param&gt;
	public delegate void CadetStartedHandler&lt;TMessage&gt;(IMessageHolder&lt;TMessage&gt; holder);

	/// &lt;summary&gt;プロセス間通信により、起動オプションなどのメッセージのやりとりをサポートするMutex&lt;/summary&gt;
	/// &lt;typeparam name=&quot;TMessage&quot;&gt;プロセス間でやりとりするメッセージの型&lt;/typeparam&gt;
	public sealed class ExtendedMutex&lt;TMessage&gt; : IMessageHolder&lt;TMessage&gt;, IDisposable
	{
		/// &lt;summary&gt;IPCで利用する共通メッセージクラス&lt;/summary&gt;
		private sealed class MutexMessage : MarshalByRefObject, IMessageHolder&lt;TMessage&gt;
		{
			#region ISyncHolder&lt;T&gt; メンバ

			private bool mIsCadet = false;

			public bool IsCadet
			{
				get
				{
					try { return mIsCadet; }
					finally { mIsCadet = true; }
				}
			}

			public TMessage Message { get; set; }

			public event CadetStartedHandler&lt;TMessage&gt; CadetStarted;

			#endregion

			public void RaiseCadetStarted(TMessage e)
			{
				Message = e;
				if (CadetStarted != null)
					CadetStarted(this);
			}
		}

		private IChannel mChannel;
		private MutexMessage mMessage;
		private ExtendedMutex(IChannel channel, MutexMessage message)
		{
			this.mChannel = channel;
			this.mMessage = message;
			this.IsCadet = message.IsCadet;
		}

		#region ISyncHolder&lt;T&gt; メンバ

		/// &lt;summary&gt;起動したプロセスが、すでに他に存在するかどうかを取得します。&lt;/summary&gt;
		public bool IsCadet { get; private set; }

		/// &lt;summary&gt;プロセス間通信オブジェクト。&lt;/summary&gt;
		public TMessage Message { get { return mMessage.Message; } }

		/// &lt;summary&gt;他のプロセスが後から起動した場合に発生するイベント。&lt;/summary&gt;
		public event CadetStartedHandler&lt;TMessage&gt; CadetStarted
		{
			add
			{
				if (mMessage != null)
					mMessage.CadetStarted += value;
			}
			remove
			{
				if (mMessage != null)
					mMessage.CadetStarted -= value;
			}
		}

		#endregion

		/// &lt;summary&gt;プロセス開始通知&lt;/summary&gt;
		/// &lt;param name=&quot;name&quot;&gt;開始プロセスのユニークな名称文字列&lt;/param&gt;
		/// &lt;param name=&quot;eventArg&quot;&gt;先に開始していた同名のプロセスがあった場合、当該プロセスに送信するメッセージ&lt;/param&gt;
		public static ExtendedMutex&lt;TMessage&gt; Start(string name, TMessage eventArg)
		{
			// 開始プロセス自体をMutexでプロセス間同期
			using (var mutex = new Mutex(true, typeof(MutexMessage).FullName + &quot;[&quot; + name + &quot;]&quot;))
			{
				bool isServer = false;
				mutex.WaitOne();
				try
				{
					#region サーバ

					// IPCチャネルの作成と登録
					var channel = new IpcServerChannel(name, &quot;remote&quot;, new BinaryServer() { TypeFilterLevel = TypeFilterLevel.Full, });
					ChannelServices.RegisterChannel(channel, true);

					// サーバとして起動できる
					isServer = true;

					RemotingConfiguration.RegisterWellKnownServiceType(typeof(MutexMessage), name, WellKnownObjectMode.Singleton);

					// メッセージキャプチャを開始
					var message = new MutexMessage() { Message = eventArg, };
					RemotingServices.Marshal(message, name, typeof(MutexMessage));
					return new ExtendedMutex&lt;TMessage&gt;(channel, message);

					#endregion
				}
				catch (RemotingException)
				{
					// サーバの起動に失敗
					if (isServer)
						throw;

					#region クライアント

					var channel = new IpcClientChannel(name, new BinaryClient());
					ChannelServices.RegisterChannel(channel, true);

					RemotingConfiguration.RegisterActivatedClientType(typeof(MutexMessage), &quot;ipc://remote/&quot; + name);

					// メッセージを発行する
					MutexMessage message = (MutexMessage)Activator.GetObject(typeof(MutexMessage), &quot;ipc://remote/&quot; + name);
					message.RaiseCadetStarted(eventArg);
					return new ExtendedMutex&lt;TMessage&gt;(channel, message);

					#endregion
				}
			}
		}

		#region IDisposable メンバ

		public void Dispose()
		{
			try { ChannelServices.UnregisterChannel(mChannel); }
			catch { }
		}

		#endregion
	}
}
</pre>
<p>中で利用している「IMessageHolder」クラス</p>
<pre class="brush: csharp;">
namespace ExMutex
{
	/// &lt;summary&gt;&lt;seealso cref=&quot;Kyoh.ExtendedMutex&quot;/&gt;で用いる、プロセス間メッセージのラッパー。&lt;/summary&gt;
	/// &lt;typeparam name=&quot;T&quot;&gt;メッセージに用いるオブジェクトの型&lt;/typeparam&gt;
	public interface IMessageHolder&lt;T&gt;
	{
		bool IsCadet { get; }
		T Message { get; }
		event CadetStartedHandler&lt;T&gt; CadetStarted;
	}
}
</pre>
<p>と、まあ。<br />
「T」やら「TMessage」っていう型アーギュメントがあるけれど、これはプロセス間でやりとりしたいオブジェクトの型を指定する。<br />
型は特に制約を持たない。基本的にはclassであることが望ましい（相互にやりとりできるし）けれど、一方通行のナニであればstructでも問題は無いと思う。<br />
また、単に通知したいだけなら、メッセージを飛ばす必要もないので、T（TMessage）にobjectを指定して、渡すメッセージはnull、でも何ら問題ない。</p>
<p>次に、どういう風に使うか、の例。<br />
GUIの場合とCUIの場合両方で書いてみた。</p>
<p>GUIの方は単に、先に走っていたプロセスがあった場合にはそのプロセスの画面（MainForm）をアクティブにする（実際にはタスクバーで点滅が起きる）という処理。ただし、CUIとして動かすために全面的にコメントアウトされているので注意。実際にはちゃんとMainFormとして画面を作らなくては動かない。</p>
<p>CUIの方では、メッセージとして
<pre class="brush: csharp;">Environment.CommandLine</pre>
<p>を渡している。つまり、呼び出しコマンドをそのまま文字列として渡している。</p>
<pre class="brush: csharp;">
using System;

namespace ExMutex
{
	public class Program
	{
		/*
		static MainForm mainForm;

		[STAThread]
		static void Main()
		{
			using(var mutex = ExtendedMutex&lt;object&gt;.Start(&quot;testProcessName&quot;, null))
			{
				if (!mutex.IsCadet)
				{
					Application.EnableVisualStyles();
					Application.SetCompatibleTextRenderingDefault(false);
					Program.mainForm = new MainForm();
						mutex.CadetStarted += new CadetStartedHandler&lt;object&gt;(CadetStarted);
					Application.Run(Program.mainForm);
				}
			}
		}

		static void CadetStarted(IMessageHolder&lt;object&gt; holder)
		{
			try { Program.mainForm.Activate(); }
			catch { }
		}
		/*/
		static void Main(string[] args)
		{
			// メッセージを文字列型で受け取るMutexに
			// コマンドラインをそのまま渡す
			using (var mutex = ExtendedMutex&lt;string&gt;.Start(&quot;testProcessName&quot;, Environment.CommandLine))
			{
				if (mutex.IsCadet)
					return;

				// 後から起動されたプロセスを処理
				mutex.CadetStarted += new CadetStartedHandler&lt;string&gt;(CadetStarted);

				// ポーリング
				string input;
				do { input = Console.ReadLine().Trim(); } while (string.IsNullOrEmpty(input));
			}
		}

		/// &lt;summary&gt;後から起動されたプロセスのメッセージを表示する&lt;/summary&gt;
		/// &lt;param name=&quot;holder&quot;&gt;表示するメッセージ&lt;/param&gt;
		static void CadetStarted(IMessageHolder&lt;string&gt; holder)
		{
			Console.WriteLine(holder.Message);
		}
		//*/
	}
}
</pre>
<p>詳しい話はそのうち気が向いたら（＝十中八九気は向かない）書くけど、<br />
要するに「先に起動した方がサーバー」「あとに起動した方はクライアント」として動作する、クライアント・サーバーモデルなあん畜生で通信してるんですよ。</p>
<p>もしかしたら、うまくいかないケースもあるかもしれない。</p>
]]></content:encoded>
			<wfw:commentRss>http://kyoh.net/?feed=rss2&amp;p=194</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>mixiへのリンクをSSL化するGreasemonkeyスクリプト [mixi SSLer]</title>
		<link>http://kyoh.net/?p=152</link>
		<comments>http://kyoh.net/?p=152#comments</comments>
		<pubDate>Thu, 12 Mar 2009 01:43:42 +0000</pubDate>
		<dc:creator>kyoh</dc:creator>
				<category><![CDATA[Firefox]]></category>
		<category><![CDATA[Others]]></category>
		<category><![CDATA[Greasemonkey Firefox]]></category>

		<guid isPermaLink="false">http://kyoh.net/?p=152</guid>
		<description><![CDATA[Firefoxのプラグイン、Greasemonkeyを使って、文書中のmixiへのリンクをssl化するスクリプト。
ご利用は自己責任で。このスクリプトならびにGreasemonkeyの利用で被った損害については、私は一切 [...]]]></description>
			<content:encoded><![CDATA[<p>Firefoxのプラグイン、<a href="http://google-mania.net/archives/213">Greasemonkey</a>を使って、文書中のmixiへのリンクをssl化するスクリプト。<br />
ご利用は自己責任で。このスクリプトならびにGreasemonkeyの利用で被った損害については、私は一切の責任を負いません。</p>
<p>といってもたいしたことはしてないので、まぁまず安全だとは思います。<br />
利用環境はFirefox 3で動作確認をしています。</p>
<p>→<a href="http://kyoh.net/wp-content/uploads/mixi_ssler.user.js">Download</a></p>
<p>→SourceCode:</p>
<pre class="brush: jscript;">// ==UserScript==
// @name           mixi ssler
// @namespace      net.kyoh.greaseMonkeys
// @description    All links to mixi(http://mixi.jp/*)in the document will be replaced to ssl format(https://mixi.jp/*).
// @author         kyoh
// @include        *
// @exclude        http://mixi.jp/*
// ==/UserScript==
for(var i = 0; i &lt; document.links.length; i++) {
if (document.links[i].host == &quot;mixi.jp:80&quot; ||
document.links[i].host == &quot;mixi.jp&quot;)
document.links[i].protocol = &quot;https:&quot;;
}</pre>
<p>[2009/3/13]<br />
つつみんぐにご指摘いただいたとおり、SSHではなくSSLでした。<br />
未だに間違える…。バカだな。<br />
文中ならびにスクリプト中の「SSH」を全て「SSL」に訂正しました。</p>
]]></content:encoded>
			<wfw:commentRss>http://kyoh.net/?feed=rss2&amp;p=152</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
