<?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>C#</title><link>http://blogs.wankuma.com/izmktr/category/1785.aspx</link><description>C#</description><managingEditor>出水 洸太郎</managingEditor><dc:language>ja-JP</dc:language><generator>.Text Version 0.95.2004.102</generator><item><dc:creator>出水 洸太郎</dc:creator><title>[C][C#]あれとは違うこれ</title><link>http://blogs.wankuma.com/izmktr/archive/2009/06/15/175461.aspx</link><pubDate>Mon, 15 Jun 2009 22:09:00 GMT</pubDate><guid>http://blogs.wankuma.com/izmktr/archive/2009/06/15/175461.aspx</guid><wfw:comment>http://blogs.wankuma.com/izmktr/comments/175461.aspx</wfw:comment><comments>http://blogs.wankuma.com/izmktr/archive/2009/06/15/175461.aspx#Feedback</comments><slash:comments>17</slash:comments><wfw:commentRss>http://blogs.wankuma.com/izmktr/comments/commentRss/175461.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/izmktr/services/trackbacks/175461.aspx</trackback:ping><description>&lt;p&gt;ネタ元＞&lt;a href="http://blogs.wankuma.com/rti/archive/2009/06/15/175382.aspx"&gt;ちょっとしたクイズです&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Rさんが問題を出していますが…実はこれ、根が深いですよ…。&lt;/p&gt; &lt;p&gt;ということで、私も問題。&lt;br&gt;言語はC#です。&lt;/p&gt; &lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:5c964292-2a4a-4839-bec5-5e740cce4abf" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;int i;
i = 0; var a = i * i++;
i = 0; var b = i * ++i;
i = 0; var c = i++ * i;
i = 0; var d = ++i * i;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;a, b, c, dの値を答えてください。&lt;/p&gt;
&lt;p&gt;C言語とC#だと結果が変わってきます。&lt;br&gt;それに、C言語の場合、i = i * i++; と書いてしまうと未定義動作です。&lt;/p&gt;
&lt;p&gt;この動作は、C# だとどうなっているのか調べてみました。&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msdn.microsoft.com/ja-jp/library/aa691322(VS.71).aspx"&gt;7.2 演算子 (C#)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;＞式のオペランドは、左から右に評価されます。&lt;br&gt;＞これは、演算子の優先順位とは異なるものであり、関係ありません。&lt;/p&gt;
&lt;p&gt;つまり、前置インクリメントであれ、後置インクリメントであれ、&lt;br&gt;インクリメントの左にある場合は古い値、右にある場合は新しい値として評価されます。&lt;/p&gt;
&lt;p&gt;そして、i *= 10;のような複合代入の場合です。&lt;br&gt;これは、i = i * 10; と展開されるため、常に古い値として評価された値との演算になります。&lt;br&gt;結果的に想定通りの答えだとしても、意外に難しい問題です。&lt;/p&gt;
&lt;p&gt;また、調べていたらこんなものを発見しました。&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msdn.microsoft.com/ja-jp/library/aa691335(VS.71).aspx"&gt;7.4.1 引数リスト (C#)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;こちらで紹介されているサンプルソースです。&lt;/p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:f461b4a8-f65f-482b-ac52-488d423e55a5" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;var i = 0;
foo (i++, i++, i++);
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これも、C言語ではやはり未定義と呼ばれているものですね。&lt;br&gt;C言語だと、引数の順序をどのように評価してもいいし、またi++が3回呼ばれるかどうかすら定かではありません。&lt;/p&gt;
&lt;p&gt;しかし、C#は正確に前から評価していくみたいなので、この呼び出しは、foo(0, 1, 2); と等価なのだそうです。&lt;br&gt;この関数を呼び終わった後のiの値は、当然3です。&lt;/p&gt;
&lt;p&gt;このあたりのC言語では未定義だったゾーンがC#ではきっちりきまっているみたいです。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/izmktr/aggbug/175461.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>出水 洸太郎</dc:creator><title>[C#]いちいちforeach</title><link>http://blogs.wankuma.com/izmktr/archive/2009/03/04/169202.aspx</link><pubDate>Wed, 04 Mar 2009 23:18:00 GMT</pubDate><guid>http://blogs.wankuma.com/izmktr/archive/2009/03/04/169202.aspx</guid><wfw:comment>http://blogs.wankuma.com/izmktr/comments/169202.aspx</wfw:comment><comments>http://blogs.wankuma.com/izmktr/archive/2009/03/04/169202.aspx#Feedback</comments><slash:comments>37</slash:comments><wfw:commentRss>http://blogs.wankuma.com/izmktr/comments/commentRss/169202.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/izmktr/services/trackbacks/169202.aspx</trackback:ping><description>&lt;p&gt;C#のforeachにはループ中にやってはいけないことがあります。&lt;br&gt;それは母体となる反復子に変更を加えることです。&lt;/p&gt; &lt;p&gt; &lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:1cbfd549-1af1-435a-b74e-1361d5ffe17a" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;static void test(){
  foreach(var item in list){
    if (item.Check()){
      //こういう風にループ中に追加してはいけない
      list.Add(item.Fork());
    }
  }
}
&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;上の例では追加ですが、削除や入れ替えもしてはいけません。&lt;br&gt;しかし、母体になっていないリストなら変更が許されます。&lt;/p&gt;
&lt;p&gt;
&lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:d43b5938-4605-4251-8673-665488d1095e" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;static void test(){
  foreach(var item in list.Where(l =&amp;gt; l.Check()).ToList()){
    list.Add(item.Fork());
  }
}
&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;ToList()を使うことで、別名のリストを作るわけですね。&lt;br&gt;こうすると、listとは違う実体に対してループが回るようになるので、&lt;br&gt;foreach内で変更ができるようになります。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/izmktr/aggbug/169202.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>出水 洸太郎</dc:creator><title>[C#]中括弧・マイナス6%　-みんなで止めようネスト化-</title><link>http://blogs.wankuma.com/izmktr/archive/2009/02/18/168310.aspx</link><pubDate>Wed, 18 Feb 2009 00:58:00 GMT</pubDate><guid>http://blogs.wankuma.com/izmktr/archive/2009/02/18/168310.aspx</guid><wfw:comment>http://blogs.wankuma.com/izmktr/comments/168310.aspx</wfw:comment><comments>http://blogs.wankuma.com/izmktr/archive/2009/02/18/168310.aspx#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://blogs.wankuma.com/izmktr/comments/commentRss/168310.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/izmktr/services/trackbacks/168310.aspx</trackback:ping><description>&lt;p&gt;ネタ元＞&lt;a href="http://bbs.wankuma.com/index.cgi?mode=al2&amp;amp;namber=32837"&gt;C#の規定の名前空間&lt;/a&gt;&lt;br&gt;こちらで、ネストが深すぎるという話が出てきます。&lt;/p&gt; &lt;p&gt;ここのところ、C#のIEnumerableでのネタを書いていますが、&lt;br&gt;これらを使うとどこまでネストが減らせるのか、どどんといきます。&lt;/p&gt; &lt;p&gt;条件に合うものだけを処理(Where)&lt;br&gt; &lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:d925e03f-b776-414b-bee6-0576ae929af7" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;[before]
foreach(var item in list){
  if (item.IsCheck()){
    ＜処理＞
  }
}

[after]
foreach(var item in list.Where(l =&amp;gt; l.IsCheck()) ){
  ＜処理＞
}
&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;二重ループ(SelectMany)&lt;br&gt;
&lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:d3f5b1a0-a2c9-4956-a0fd-e6a8f0fdc596" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;[before]
foreach(var item in list){
  foreach(var childitem in item.childlist){
    ＜処理＞
  }
}

[after]
foreach(var item in list.SelectMany(l =&amp;gt; l.childlist) ){
  ＜処理＞
}
&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;最初に見つかる要素を探す(FirstOrDefault)&lt;br&gt;最後に見つかる要素を探す場合はLastOrDefaultを使います。&lt;/p&gt;
&lt;p&gt;
&lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:10eeb101-94c0-4bf4-8af8-1b02478c1323" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;[before]
TestClass find = null;
foreach(var item in list){
  if (item.Check()){
    find = item;
    break;
  }
}

[after]
var find = list.FirstOrDefault(l =&amp;gt; l.Check());
&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;すべての要素が条件に合うか(All)&lt;br&gt;どれか一つの要素が条件に合うかではContainsを使います。&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:86de3f8d-682b-492f-b808-a17cb2c90c00" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;[before]
bool flag = true;
foreach(var item in list){
  if (item.Check() == false){
    flag = false;
    break;
  }
}

[after]
bool flag = list.All(l =&amp;gt; l.Check() );
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;条件にあう要素があったらそこで打ち切る(TakeWhile)&lt;br&gt;最初から100個という場合はTakeを使います。&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:afdbef8e-e56d-46f2-8e24-28621d3dd8d4" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;[before]
foreach(var item in list){
  if (item.Check() == false) break;
  ＜処理＞
}

[after]
foreach(var item in list.TakeWhile(l =&amp;gt; l.Check()) ){
  ＜処理＞
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;条件にあう要素が出てくるまで処理を行わない(SkipWhile)&lt;br&gt;最初の100個を無視して残りだけという場合はSkipを使います。&lt;br&gt;Whereと違って一度条件に合う要素があれば、それ以降の要素が条件に合わなくても処理が行われます。
&lt;p&gt;
&lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:980ec664-edc2-42af-8548-3784ac2f4730" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;[before]
int i;
for (i = 0; i &amp;lt; list.Count; i++)
  if (list[i].Check()) break;
}

for (; i &amp;lt; list.Count; i++){
  ＜処理＞
}

[after]
foreach(var item in list.SkipWhile(l =&amp;gt; l.Check()) ){
  ＜処理＞
}
&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;ネストはgotoの化身です。&lt;br&gt;ネストが4，5段あたりになるようなら、これらの構文を使ってネストを減らすようにするべきでしょう。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/izmktr/aggbug/168310.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>出水 洸太郎</dc:creator><title>[C#]何度目の動き</title><link>http://blogs.wankuma.com/izmktr/archive/2009/02/17/168255.aspx</link><pubDate>Tue, 17 Feb 2009 10:51:00 GMT</pubDate><guid>http://blogs.wankuma.com/izmktr/archive/2009/02/17/168255.aspx</guid><wfw:comment>http://blogs.wankuma.com/izmktr/comments/168255.aspx</wfw:comment><comments>http://blogs.wankuma.com/izmktr/archive/2009/02/17/168255.aspx#Feedback</comments><slash:comments>759</slash:comments><wfw:commentRss>http://blogs.wankuma.com/izmktr/comments/commentRss/168255.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/izmktr/services/trackbacks/168255.aspx</trackback:ping><description>&lt;p&gt;foreachでループ回数を取得する方法です。&lt;/p&gt; &lt;p&gt;IEnumerable.Select()には、引数を2つ取るデリゲートを渡すことができます。&lt;br&gt;この2つ目の引数がループカウンターです。&lt;br&gt;具体的には以下のようなソースになります。&lt;br&gt;&lt;/p&gt; &lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:347722ed-f3a0-4b35-a221-9fb3a898181a" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;static void Test(){
  LinkedList&amp;lt;string&amp;gt; name = new LinkedList&amp;lt;string&amp;gt;();

  name.AddLast("Carrot");
  name.AddLast("Sandal");
  name.AddLast("Yacht");
  name.AddLast("Sesame");
  name.AddLast("Rocket");
  name.AddLast("Turkey");
  name.AddLast("Bee");
  name.AddLast("Whale");
  name.AddLast("Juice");
  name.AddLast("Strawberry");

  foreach(var item in name.Select((n, i) =&amp;gt; new{name = n, index = i})) {
    Console.WriteLine(string.Format("{0}:{1}", item.index + 1, item.name));
  }
}

＜実行結果＞
1:Carrot
2:Sandal
3:Yacht
4:Sesame
5:Rocket
6:Turkey
7:Bee
8:Whale
9:Juice
10:Strawberry
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Listや配列型ならforでまわしてdata[i]の形式で取得すればいいですが、&lt;br&gt;LinkedListのようなランダムアクセスできない型だと便利だと思います。&lt;/p&gt;
&lt;p&gt;#LINQ構文でrow_num相当のものがありそうだと思ったんだけど、ないなぁ～&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/izmktr/aggbug/168255.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>出水 洸太郎</dc:creator><title>[C#]forever for</title><link>http://blogs.wankuma.com/izmktr/archive/2009/02/12/168051.aspx</link><pubDate>Thu, 12 Feb 2009 22:00:00 GMT</pubDate><guid>http://blogs.wankuma.com/izmktr/archive/2009/02/12/168051.aspx</guid><wfw:comment>http://blogs.wankuma.com/izmktr/comments/168051.aspx</wfw:comment><comments>http://blogs.wankuma.com/izmktr/archive/2009/02/12/168051.aspx#Feedback</comments><slash:comments>18</slash:comments><wfw:commentRss>http://blogs.wankuma.com/izmktr/comments/commentRss/168051.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/izmktr/services/trackbacks/168051.aspx</trackback:ping><description>&lt;p&gt;IEnumrableが使えば使うほど楽しいです。&lt;/p&gt; &lt;p&gt;例としてマインスイーパーを作るとします。&lt;br&gt; &lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:6e331832-3dfb-432a-afe0-ddcdb14b8064" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;class Cell{
  public bool isMine();
}

class Field{
  public Cell GetCell(int x, int y){
    if (x &amp;lt; 0 || maxx &amp;lt;= x) return null;
    if (y &amp;lt; 0 || maxx &amp;lt;= y) return null;
    return cell[x,y];
  }
}&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;GetCellでセルクラスを取得できますが、範囲外を取得しようとするとnullを返します。&lt;br&gt;isMine()は爆弾がセルにあればtrue,なければfalseを返します。&lt;/p&gt;
&lt;p&gt;こういうとき、周りの8マスを調べて爆弾の値をとりたい、と考えるとどう書けばいいでしょうか。&lt;br&gt;
&lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:df13149b-5938-45e9-b9b1-b4a0f8fbb351" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;class Field{
  public IEnumrable&amp;lt;Cell&amp;gt; Get8Round(int x, int y){
    yield return GetCell(x - 1, y - 1);
    yield return GetCell(x    , y - 1);
    yield return GetCell(x + 1, y - 1);
    yield return GetCell(x - 1, y    );
    yield return GetCell(x + 1, y    );
    yield return GetCell(x - 1, y + 1);
    yield return GetCell(x    , y + 1);
    yield return GetCell(x + 1, y + 1);
  }
  
  public int GetMineNum(int x, int y){
    return Get8Round(x, y).Count(l =&amp;gt; l != null &amp;amp;&amp;amp; l.isMine());
  }
}
&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;今回の肝は８近傍を返す関数というところにあります。&lt;br&gt;中身は泥臭い方法で実装していますが、一度作ってしまえばこれを使いまわせます。&lt;/p&gt;
&lt;p&gt;周り8マスの集合を作り、nullでなくてisMine()がtrueの個数、という風に&lt;br&gt;頭で思いついた通りに打つだけでその通りにできるうえ、&lt;br&gt;インデックスやカウンター用の変数が出てこなくて済む、というのはありがたいです。&lt;/p&gt;
&lt;p&gt;考えてみれば、for文を絡む部分はモジュール化しにくい部分でした。&lt;br&gt;８近傍を取る部分が出てくるたびにどこかにあるforをコピペして使っていました。&lt;br&gt;また、そのためにoffsetx[8], offsety[8]というものをグローバル領域に取ったりもしていました。
&lt;p&gt;正直、for文というのは可読性がよくないように思います。&lt;br&gt;yieldを使えば簡単にモジュール化できるうえ、IEnumrableに便利な関数が増えているので、&lt;br&gt;for文をあまり使わないコーディングスタイルもありではないでしょうか。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/izmktr/aggbug/168051.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>出水 洸太郎</dc:creator><title>[C#]コンプレックスが倒せない</title><link>http://blogs.wankuma.com/izmktr/archive/2009/02/05/167538.aspx</link><pubDate>Thu, 05 Feb 2009 15:08:00 GMT</pubDate><guid>http://blogs.wankuma.com/izmktr/archive/2009/02/05/167538.aspx</guid><wfw:comment>http://blogs.wankuma.com/izmktr/comments/167538.aspx</wfw:comment><comments>http://blogs.wankuma.com/izmktr/archive/2009/02/05/167538.aspx#Feedback</comments><slash:comments>519</slash:comments><wfw:commentRss>http://blogs.wankuma.com/izmktr/comments/commentRss/167538.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/izmktr/services/trackbacks/167538.aspx</trackback:ping><description>&lt;p&gt;&lt;a href="http://blogs.wankuma.com/izmktr/archive/2009/02/05/167489.aspx"&gt;[C#]コンプレックスと戦う&lt;/a&gt;の続き&lt;br&gt;C#で複素数を扱う挑戦はまだまだ続きます。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:4665cd6c-259a-4b43-a70e-191b2b1378ef" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;static void Main(string[] args){
  Complex&amp;lt;float&amp;gt;.SetFunc((x, y) =&amp;gt; x + y, (x, y) =&amp;gt; x - y, (x, y) =&amp;gt; x * y);
  Complex&amp;lt;float&amp;gt; a = new Complex&amp;lt;float&amp;gt;(1.0f, -3.0f);
  Complex&amp;lt;float&amp;gt; b = new Complex&amp;lt;float&amp;gt;(2.0f, 6.0f);

  var c = a + b;
  var d = a - b;
  var e = a * b;

  Console.WriteLine(a + " + " + b + " = " + c);
  Console.WriteLine(a + " - " + b + " = " + d);
  Console.WriteLine(a + " * " + b + " = " + e);
}

＜実行結果＞
(1+-3i) + (2+6i) = (3+3i)
(1+-3i) - (2+6i) = (-1+-9i)
(1+-3i) * (2+6i) = (20+0i)
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;てへっ♪ やっちゃった♪&lt;/p&gt;
&lt;p&gt;0+1iって表記は目を瞑るとしても、1+-9iはちょっと許容しがたいです。&lt;br&gt;ついでに、20+0iみたいに虚数部が0なら虚数部省略して実数っぽく見せたいところです。&lt;/p&gt;
&lt;p&gt;ICompareableを追加してこんな感じですかね？&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:f41fced7-f3db-4d6c-ae6a-5db4473a4a05" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;public class Complex&amp;lt;T&amp;gt;
where T:IComparable{
  public override string ToString(){
    if (im.CompareTo(0) &amp;lt; 0){
      return "(" + re + "" + im + "i)";
    }else if(im.CompareTo(0) == 0){
      return re.ToString();
    }else{
      return "(" + re + "+" + im + "i)";
    }
  }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;しかし、このコードはコンパイルは通るのですが、実行時に以下のようなエラーを発生します。 
&lt;p&gt;ハンドルされていない例外: System.ArgumentException: オブジェクトは Single 型でなければなりません。&lt;br&gt;&amp;nbsp;&amp;nbsp; 場所 System.Single.CompareTo(Object value)&lt;br&gt;&amp;nbsp;&amp;nbsp; 場所 test.Complex`1.ToString() 
&lt;p&gt;エラーの意味がわかりづらいですが、どうやら im.CompareTo(0)がまずいようです。&lt;br&gt;im.CompareTo(0.0f)に書き換えると動くので、0がint型なのが問題のようですね。&lt;/p&gt;
&lt;p&gt;ということで、キャストして再挑戦。&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:3b024558-3a66-460a-817f-755689bb4426" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;public class Complex&amp;lt;T&amp;gt;
where T:IComparable{
  public override string ToString(){
    if (im.CompareTo((T) 0) &amp;lt; 0){
      return "(" + re + "" + im + "i)";
    }else if(im.CompareTo((T) 0) == 0){
      return re.ToString();
    }else{
      return "(" + re + "+" + im + "i)";
    }
  }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;エラー CS0030: 型 'int' を型 'T' に変換できません。&lt;/p&gt;
&lt;p&gt;なるほど、Tがintへのキャストを持っているかどうかわからないため、こういう構文も許されないらしいです。&lt;/p&gt;
&lt;p&gt;ならば…0という値を使わずに0と比較すればいいわけです。&lt;br&gt;そこで、C#の数値型はデフォルトの時0が入ることに着目しました。&lt;br&gt;これが答えに違いない！！&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:f12d4135-7cd0-4111-b68b-6dc2982c267f" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;public class Complex&amp;lt;T&amp;gt;
where T:IComparable{
  static T zero = new T();

  public override string ToString(){
    if (im.CompareTo(zero) &amp;lt; 0){
      return "(" + re + "" + im + "i)";
    }else if(im.CompareTo(zero) == 0){
      return re.ToString();
    }else{
      return "(" + re + "+" + im + "i)";
    }
  }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;エラー CS0304: 変数型 'T' のインスタンスは、new() 制約を含まないため、作成できません。&lt;/p&gt;
&lt;p&gt;new()制約とは引数のないコンストラクタをもつ制約で、これならばwhere文に追加できます。&lt;br&gt;それを追加したソースがこちら。&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:64fc8eff-99a1-4b8b-957f-8d979d2a6455" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;public class Complex&amp;lt;T&amp;gt;
  where T:IComparable, new(){
  ＜中略＞
}

＜実行結果＞
(1-3i) + (2+6i) = (3+3i)
(1-3i) - (2+6i) = (-1-9i)
(1-3i) * (2+6i) = 20&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;コンパイルも通るし、思い通りの結果になりました。&lt;/p&gt;
&lt;p&gt;仮に、この小細工なしで言語拡張で対応する場合、どんな構文があればいいのか、を考えると、&lt;br&gt;intからキャストできる制約を作る、というのは理想の回答とは微妙に違う気がします。&lt;/p&gt;
&lt;p&gt;今回欲しかった関数は、符号を得る関数ですね。&lt;br&gt;よって、理想の回答は符号を得る関数を持つインターフェースを制約条件として追加するでしょう。&lt;br&gt;ExcelにはSIGN関数がありますが、普通は理由がない限り作らない関数のため、まさにニッチすぎて誰得仕様。&lt;/p&gt;
&lt;p&gt;なんとももやもやした結果です。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/izmktr/aggbug/167538.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>出水 洸太郎</dc:creator><title>[C#]コンプレックスと戦う</title><link>http://blogs.wankuma.com/izmktr/archive/2009/02/05/167489.aspx</link><pubDate>Thu, 05 Feb 2009 06:31:00 GMT</pubDate><guid>http://blogs.wankuma.com/izmktr/archive/2009/02/05/167489.aspx</guid><wfw:comment>http://blogs.wankuma.com/izmktr/comments/167489.aspx</wfw:comment><comments>http://blogs.wankuma.com/izmktr/archive/2009/02/05/167489.aspx#Feedback</comments><slash:comments>171</slash:comments><wfw:commentRss>http://blogs.wankuma.com/izmktr/comments/commentRss/167489.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/izmktr/services/trackbacks/167489.aspx</trackback:ping><description>&lt;P&gt;ネタ元＞&lt;A href="http://blogs.wankuma.com/episteme/archive/2009/02/04/167390.aspx"&gt;あらあらあら&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;C#には同じインターフェースを持たない同士でのジェネリックが定義できないという&lt;BR&gt;多分、C#2.0が発表されてからずっと言われ続けただろう話題ですね。&lt;/P&gt;
&lt;P&gt;ということで、ちょっとがんばって複素数クラスを作ってみました。&lt;BR&gt;
&lt;PRE class=c# style="DISPLAY: none" name="code"&gt;
public class Complex&amp;lt;T&amp;gt;{
  public T re { get; set; }
  public T im { get; set; }
  static public Func&amp;lt;T, T, T&amp;gt; add { get; set; }
  static public Func&amp;lt;T, T, T&amp;gt; sub { get; set; }
  static public Func&amp;lt;T, T, T&amp;gt; multi { get; set; }
  public static Complex&amp;lt;T&amp;gt; operator +(Complex&amp;lt;T&amp;gt; lft, Complex&amp;lt;T&amp;gt; rgt){
    return new Complex&amp;lt;T&amp;gt;(add(lft.re, rgt.re), add(lft.im, rgt.im));
  }
  public static Complex&amp;lt;T&amp;gt; operator -(Complex&amp;lt;T&amp;gt; lft, Complex&amp;lt;T&amp;gt; rgt){
    return new Complex&amp;lt;T&amp;gt;(sub(lft.re, rgt.re), sub(lft.im, rgt.im));
  }
  public static Complex&amp;lt;T&amp;gt; operator *(Complex&amp;lt;T&amp;gt; lft, Complex&amp;lt;T&amp;gt; rgt){
    return new Complex&amp;lt;T&amp;gt;(sub(multi(lft.re, rgt.re), multi(lft.im, rgt.im)),
      add(multi(lft.re, rgt.im), multi(lft.im, rgt.re)));
  }
  public override string ToString(){
    return "("+re + "+" + im + "i)";
  }
  public Complex(T re, T im){
    this.re = re;
    this.im = im;
  }
  public static void SetFunc(Func&amp;lt;T, T, T&amp;gt; add, Func&amp;lt;T, T, T&amp;gt; sub, Func&amp;lt;T, T, T&amp;gt; multi){
    Complex&amp;lt;T&amp;gt;.add = add;
    Complex&amp;lt;T&amp;gt;.sub= sub;
    Complex&amp;lt;T&amp;gt;.multi = multi;
  }
}
&lt;/PRE&gt;
&lt;P&gt;そして、こうやって使います。&lt;/P&gt;
&lt;P&gt;&lt;/P&gt;
&lt;PRE class=c# style="DISPLAY: none" name="code"&gt;
static void Main(string[] args){
  Complex&amp;lt;float&amp;gt;.SetFunc((x, y) =&amp;gt; x + y, (x, y) =&amp;gt; x - y, (x, y) =&amp;gt; x * y);
  Complex&amp;lt;float&amp;gt; a = new Complex&amp;lt;float&amp;gt;(5.0f, 3.0f);
  Complex&amp;lt;float&amp;gt; b = new Complex&amp;lt;float&amp;gt;(2.0f, 1.0f);
  var c = a + b;
  var d = a - b;
  var e = a * b;
  Console.WriteLine(a + " + " + b + " = " + c);
  Console.WriteLine(a + " - " + b + " = " + d);
  Console.WriteLine(a + " * " + b + " = " + e);
}
&amp;lt;実行結果&amp;gt;
(5+3i) + (2+1i) = (7+4i)
(5+3i) - (2+1i) = (3+2i)
(5+3i) * (2+1i) = (7+11i)
&lt;/PRE&gt;
&lt;P&gt;ここで、addにあたる部分をoperator +の名前を持ち、Func&amp;lt;T, T, T&amp;gt;の形でstaticなものを探し出して&lt;BR&gt;自動的に定義してくれればいいんですけどね～。&lt;BR&gt;リフレクション使ってうまいこと出来ないかなぁ&amp;#8230;。&lt;/P&gt;
&lt;PRE class=c# style="DISPLAY: none" name="code"&gt;
public class Complex&amp;lt;T&amp;gt;
where 
static T oprator + (T, T), 
static T oprator - (T, T), 
static T oprator * (T, T){
  ＜中略＞
}
&lt;/PRE&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;こんな構文ができるようにしてほしいです、ほんと。&lt;/P&gt;&lt;img src ="http://blogs.wankuma.com/izmktr/aggbug/167489.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>出水 洸太郎</dc:creator><title>[C#]LINQの世界</title><link>http://blogs.wankuma.com/izmktr/archive/2009/01/30/167177.aspx</link><pubDate>Fri, 30 Jan 2009 18:17:00 GMT</pubDate><guid>http://blogs.wankuma.com/izmktr/archive/2009/01/30/167177.aspx</guid><wfw:comment>http://blogs.wankuma.com/izmktr/comments/167177.aspx</wfw:comment><comments>http://blogs.wankuma.com/izmktr/archive/2009/01/30/167177.aspx#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://blogs.wankuma.com/izmktr/comments/commentRss/167177.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/izmktr/services/trackbacks/167177.aspx</trackback:ping><description>&lt;p&gt;&lt;a href="http://blogs.wankuma.com/izmktr/archive/2009/01/29/167116.aspx"&gt;[C#]組み合わせ小細工&lt;/a&gt;の続き。&lt;/p&gt; &lt;p&gt;0～9の数字を1回づつ使って、4桁-3桁=3桁の式を完成しろ、という問題をもう少し考えてみます。&lt;/p&gt; &lt;p&gt;4桁の最上位桁は1以外ありません。&lt;br&gt;また、前回のコメントに合ったとおり、最上位桁が0というパターンは除外しなければなりません。&lt;br&gt;（今回はたまたま考慮の必要がない問題だったので除外処理を省いていましたが。）&lt;/p&gt; &lt;p&gt;ということで、それらを踏まえて、前回のソースを改良してみました。&lt;/p&gt; &lt;p&gt; &lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:04e1cfaf-1efe-4490-9db4-abd59db9a7b6" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;static void Main(string[] args) {
  int[] num = (from n in Enumerable.Range(0, 10) where n != 1 select n ).ToArray();

  var perm = from n in Permutation(num) where n[3] != 0 &amp;amp;&amp;amp; n[6] != 0 select n;

  foreach(var item in perm) {
      int a = item[0] * 100 + item[1] * 10 + item[2] + 1000;
      int b = item[3] * 100 + item[4] * 10 + item[5] ;
      int c = item[6] * 100 + item[7] * 10 + item[8] ;
      if(a - b == c) Console.WriteLine(a + "-" + b + "=" + c);
  }
}
&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;0～9（ただし1は除く）という配列を生成し、3桁の百の位が0というパターンを除外しています。&lt;br&gt;LINQに除去処理を任せているので、ループ部分がすっきりします。&lt;/p&gt;
&lt;p&gt;個人的には気に入った書式です。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/izmktr/aggbug/167177.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>出水 洸太郎</dc:creator><title>[C#]組み合わせ小細工</title><link>http://blogs.wankuma.com/izmktr/archive/2009/01/29/167116.aspx</link><pubDate>Thu, 29 Jan 2009 16:05:00 GMT</pubDate><guid>http://blogs.wankuma.com/izmktr/archive/2009/01/29/167116.aspx</guid><wfw:comment>http://blogs.wankuma.com/izmktr/comments/167116.aspx</wfw:comment><comments>http://blogs.wankuma.com/izmktr/archive/2009/01/29/167116.aspx#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://blogs.wankuma.com/izmktr/comments/commentRss/167116.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/izmktr/services/trackbacks/167116.aspx</trackback:ping><description>&lt;P&gt;C++だと、next_premutation,ってのがあるので、組み合わせの生成が楽ですが、&lt;BR&gt;C#だと似たようなものもないと思われるので作ってみました。&lt;/P&gt;
&lt;P&gt;
&lt;DIV class=wlWriterSmartContent id=scid:812469c5-0cb0-4c63-8c15-c81123a09de7:8087eb20-d217-4cbb-9d76-095b774a6f3b style="PADDING-RIGHT: 0px; DISPLAY: inline; PADDING-LEFT: 0px; FLOAT: none; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px"&gt;&lt;PRE class=c# name="code"&gt;
static void Swap&amp;lt;T&amp;gt;(ref T lhs, ref T rhs) {
  T temp;
  temp = lhs;
  lhs = rhs;
  rhs = temp;
}
static void Reverse&amp;lt;T&amp;gt;(T[] array, int start, int count) {
  for(int i = 0; i &amp;lt; count / 2; i++) {
    Swap(ref array[start + i], ref array[start + count - i - 1]);
  }
}
public static T[] PermutationNext&amp;lt;T&amp;gt;(T[] result)
where T : IComparable {
  var max = result[result.Length - 1];
  for(int i = result.Length - 1; 0 &amp;lt;= i; i--) {
    if(max.CompareTo(result[i]) &amp;lt;= 0) {
      max = result[i];
    } else {
      int sc;
      for(sc = i + 1; sc &amp;lt; result.Length; sc++) {
        if(result[sc].CompareTo(result[i]) &amp;lt;= 0) {
          break;
        }
      }
      Swap(ref result[i], ref result[sc - 1]);
      Reverse(result, i + 1, result.Length - i - 1);
      return result;
    }
  }
  return null;
}
public static IEnumerable&amp;lt;T[]&amp;gt; Permutation&amp;lt;T&amp;gt;(IEnumerable&amp;lt;T&amp;gt; array)
where T : IComparable {
  var result = (from n in array orderby n select n).ToArray();
  for(; ; ) {
    yield return result;
    result = PermutationNext(result);
    if(result == null) break;
  }
}
&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;たとえば、0～9の数字を1回づつ使って、4桁-3桁=3桁の式を完成しろ、という問題なら、&lt;BR&gt;こんな感じで書けばよいです。&lt;/P&gt;
&lt;P&gt;
&lt;DIV class=wlWriterSmartContent id=scid:812469c5-0cb0-4c63-8c15-c81123a09de7:cf3046dc-08d1-45dc-aea3-7ca87abff40e style="PADDING-RIGHT: 0px; DISPLAY: inline; PADDING-LEFT: 0px; FLOAT: none; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px"&gt;&lt;PRE class=c# name="code"&gt;static void Main(string[] args) {
  int[] num = (from n in Enumerable.Range(0, 10) select n).ToArray();

  foreach(var item in Permutation(num)) {
    if(item[0] == 0) continue;
    int a = item[0] * 1000 + item[1] * 100 + item[2] * 10 + item[3];
    int b = item[4] * 100 + item[5] * 10 + item[6];
    int c = item[7] * 100 + item[8] * 10 + item[9];

    if(a - b == c) Console.WriteLine(a + "-" + b + "=" + c);
  }
}
&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;仕組みは過去記事の[&lt;A href="http://blogs.wankuma.com/izmktr/archive/2008/07/25/150189.aspx"&gt;[数学]最後尾はここではありません！&lt;/A&gt;]を参考にしてください。&lt;/P&gt;&lt;img src ="http://blogs.wankuma.com/izmktr/aggbug/167116.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>出水 洸太郎</dc:creator><title>[C#]最小と最大</title><link>http://blogs.wankuma.com/izmktr/archive/2009/01/25/166774.aspx</link><pubDate>Sun, 25 Jan 2009 06:54:00 GMT</pubDate><guid>http://blogs.wankuma.com/izmktr/archive/2009/01/25/166774.aspx</guid><wfw:comment>http://blogs.wankuma.com/izmktr/comments/166774.aspx</wfw:comment><comments>http://blogs.wankuma.com/izmktr/archive/2009/01/25/166774.aspx#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://blogs.wankuma.com/izmktr/comments/commentRss/166774.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/izmktr/services/trackbacks/166774.aspx</trackback:ping><description>&lt;p&gt;&lt;a href="http://blogs.wankuma.com/izmktr/archive/2009/01/24/166763.aspx"&gt;前回の続き。&lt;/a&gt;&lt;br&gt;C#で書いてみました。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:e1262666-0aeb-4a11-a044-d2db02025679" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;/* funcは適当 */
static int func(int x) { return x * 109 % 257; }

static void Test(){
  var result = from n in Enumrable.Range(1, 10) select func(n);

  Console.WriteLine(result.Max());
  Console.WriteLine(result.Min());
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;LINQが来てから遅延評価の配列型の取り扱いが格段に楽ですね。&lt;br&gt;C++だとここまでスマートにいかないのが難点。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/izmktr/aggbug/166774.aspx" width = "1" height = "1" /&gt;</description></item></channel></rss>