R.Tanaka.Ichiro's Blog

主にC# な話題です

目次

Blog 利用状況

ニュース

C#3.0の新機能

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace WindowsFormsApplication1 {
  public partial class Form1 : Form {
    public object Value { get; private set; }
    public Form1() {
      InitializeComponent();
      var c = new[] {
        new { Code = 34,  Name = "R・田中一郎",  Age = 18 },
        new { Code = 51,  Name = "ぽぴ王子 ",    Age = 18 },
        new { Code = 111,  Name = "IIJIMAS",    Age = 20 },
      };
      var q1 = from x in c where x.Age == 18 select new { Code = x.Code, Name = x.Name };
      var q2 = c.Where(x => x.Age == 18).Select(x => new { Code = x.Code, Name = x.Name });
      var q3 = c.条件式(x => x.Age == 18).選択(x => new { Code = x.Code, Name = x.Name });
      combo.DataSource = q3;
      combo.ValueMember = "Code";
      combo.DisplayMember = "Name";
      combo.SelectedValueChanged += (sender, e) => Value = this.combo.SelectedValue;
    }
  }
  public static class Extensions {
    public static IEnumerable 条件式(this IEnumerable value, Func func) {
      var r = new List();
      foreach(var x in value) if (func(x)) r.Add(x);
      return r;
    }
    public static IEnumerable 選択(this IEnumerable value, Func func) {
      return value.Select(x => func(x));
    }
  }
}


C#3.0の新機能

は LINQ のためにあるという言葉を聞いたことがあります。

ってことは、新機能を駆使して書く場合に一番適当なコードは何だろうと考えた時、LINQ の中身を想像して書くことが一番手っ取り早いんじゃないかと思ってみた訳です。

上記のコードは、一般的な Windows アプリケーションで、Form1 に combo というコンボボックスを配置するだけで問題なく動作します。

q1,q2, q3 を差し替えてみると全く同じ結果が得られることが確認できます。

このコードを読むためには、C#3.0 の新機能を知っている必要があるので、逆に、このコードが読めれば C#3.0 の新機能は、ある程度理解できているのかな、と思ったりしました。

投稿日時 : 2007年12月29日 13:19

Feedback

# re: C#3.0の新機能 2007/12/29 13:51 IIJIMAS

こんにちは、IIJIMAS@Rさんファンです。

Rさんの前の勉強会の資料でも突っ込みたかったのですが、Rさんいらっしゃらなかったので。

なぜに私が、Rさんや王子殿下より年上なんですかっw!

#個人的に年末年始休暇はC#やVS2008勉強しようと思っているので、タイムリーな気もしますがwww

# re: C#3.0の新機能 2007/12/29 16:41 えムナウ

私のこのページでも解説しています。

C#3.0の言語拡張
http://mnow.jp/tabid/203/Default.aspx

# re: C#3.0の新機能 2007/12/29 18:27 とおりすがり

ズコー

# re: C#3.0の新機能 2007/12/29 18:46 επιστημη

年の瀬の慌ただしい中、バグっております。
変数 x がどこにも宣言されておりません。

# re: C#3.0の新機能 2007/12/29 19:01 R・田中一郎

IIJIMAS さん

>なぜに私が、Rさんや王子殿下より年上なんですかっw!

勝手に名前使ってごめんなさい^^;
まぁ、20歳ならお酒飲めるし、いいじゃありませんか。

--------------------------------
えムナウ さん

>私のこのページでも解説しています。

C#2.0で書いてみるというのは思いつかなかったです。
これは勉強になりますね。

--------------------------------
とおりすがり さん

>ズコー

ええ、本当に「ズコー」ですよね。

--------------------------------
επιστημη さん

>年の瀬の慌ただしい中、バグっております。

うーん、逆に読みにくくなると思って、修正した部分がバグってましたね。
ご指摘ありがとうございました。

# re: C#3.0の新機能 2007/12/29 21:18 NyaRuRu

>C#3.0の新機能
以下のコードがコンパイルできるようになったとかもいかがですか?
型推論が強化されたことを示す一例です.

using System;
public delegate TResult Func<TResult>();
static class Program
{
  static Func<T> F<T>(Func<T> f)
  {
    return f;
  }
  static void Main(string[] args)
  {
    Func<int> f = F(delegate { return 1; });
    Console.WriteLine(f());

    //以下なら C# 2.0 でもコンパイル可能
    //Func<int> f = F<int>(delegate { return 1; });
  }
}

# re: C#3.0の新機能 2007/12/29 21:30 NyaRuRu

C# 2.0 でも以下の式は OK ですね.
using System;
public delegate TResult Func<TResult>();
class Program
{
  static Func<T> F<T>(Func<T> f, T dummy)
  {
    return f;
  }
  static void Main(string[] args)
  {
    Func<int> f = F(delegate { return 1; }, 1);
  }
}

ちなみにこれがなんで重要かというと,匿名型の型名が書けないという問題があるためです.
つまり,C# 2.0 の推論規則のまま var を導入しても以下のようになってしまいうまくありません.
var f = F<ここの型名が書けない>(delegate { return new {Num=1}; });

C# 2.0 の推論規則のままいくのであれば,不格好ですが,このようにする必要があります.
var f = F(delegate { return new {Num=1}; }, new {Num=1} );

実際は推論規則が強化されたので,こういった事態は避けることができました.

# re: C#3.0の新機能 2007/12/29 21:37 NyaRuRu

というわけで,「C# 3.0 の新しい構文/キーワードを使わなければ,C# 2.0 でそのままコンパイルできるコードになる」というのは嘘ですのでご注意を.

# re: C#3.0の新機能 2007/12/30 9:21 R・田中一郎

ああ、そうか・・・

2.0は、「T dummy」の部分がないと推論が働かないってことですね。

10分程悩みました^^;
確かに、この差は大きいですね。

# re: C#3.0の新機能 2007/12/30 14:44 NyaRuRu

「強力な型推論」とか「型推論が弱い」とかで議論になるのは,普通これ系の話ですからねぇ.

var がやっている型推論は最も単純な部類に属する奴です.振る舞い自体は C++ 屋さんなら既におなじみなはずで,本当なら「ああ,あれね」で済むはずなのですが.

static Type instance_typeof<T>(T arg)
{
  return typeof(Type);
}
static void Main(string[] args)
{
  var i = 1;
  Type type = instance_typeof(1);
}

# re: C#3.0の新機能 2007/12/30 14:45 NyaRuRu

うはミスった.

static Type instance_typeof<T>(T arg)
{
  return typeof(T);
}
static void Main(string[] args)
{
  var i = 1;
  Type type = instance_typeof(1);
}

ですね.

# re: C#3.0の新機能 2007/12/30 14:48 NyaRuRu

instance_typeof だと o.GetType() みたいだから,literal_typeof とか variable_typeof とかの方がいいかも.
うーむ,英語の語彙が足らん.

# re: C#3.0の新機能 2007/12/30 15:25 R・田中一郎

>うーむ,英語の語彙が足らん.

大丈夫です。
言わんとすることはわかりましたから^^;

# re: C#3.0の新機能 2008/05/08 15:35 Streetw☆

古いエントリだけどコメントさせてもらいます。

「R流・10分で分かるVisul Studio 2008 C#の新機能」の資料いただきました。
ぎゅっっとつまってますね!
#このエントリにつまってたことに今気付きましたw

それで最近、コレクション初期化子について調べてたんですが、
資料のRさんの例って、C#言語仕様v1.2の「12.6 配列初期化子」
じゃないかなって思いました。どうですか?
コレクション初期化子って、Addメソッドが自動的に実行されるのが
ポイントみたいで、IEnumerable+Add()がコレクション初期化子の
対象みたいです。
IEnumerableの必要性はよくわからないんですけど...
#それと、日付が未来でした~

# re: C#3.0の新機能 2008/05/08 15:37 Streetw☆

>資料のRさんの例

上の本文の
var c = new[] {
のところです。

# re: C#3.0の新機能 2008/05/09 16:43 R・田中一郎

あっ、本当だ!
そうですそうです。

ご指摘の通り配列初期化子です。

>IEnumerableの必要性はよくわからないんですけど...

LINQ to Objects が実行できる条件として、IEnumerable を継承している必要があるみたいです。

僕としては、最初のデータソースを作っている部分に関しては、LINQ が吐き出す内容と同様のものを簡便に作るための機能という位置づけなのかな、と勝手に解釈しています^^;

# re: C#3.0の新機能 2008/05/09 17:15 Streetw☆

>あっ、本当だ!

あっ、気付いてもらえた!
メールする方が良かったかなって心配でしたw

Addメソッドを持ってても、LINQするときとかのIEnumerableできないようなものは
きっとコレクションじゃないから、初期化子を使う必要ないってことですね!
っと、私も勝手に解釈しておきますw
モヤモヤがとれました♪

# re: C#3.0の新機能 2008/05/09 17:32 R・田中一郎

反応はやっ。
RSS 拾ってるんですか?

それと、Streetw☆ さんは何者なんでしょうか?^^;

ブログとか公開してたら RSS フィールド登録しておきたいのですがー

# re: C#3.0の新機能 2008/05/09 17:51 Streetw☆

速かったのはたまたまです;
気付いてもらえるか心配でしたから何度も来てましたw
Rさんの、はてなのR日記も週に一度は見てます。
でも更新されないの(¬_¬)
#冗談ですw
私はブログとかは全然してません。
とりこびとさんとこのコメント欄によくいます。登録はそちらを・・・w
#せっかく言ってくださったのに冗談で返してごめんなさい。

# re: 全然ついてイケてない、日曜プログラマのタ・ワ・ゴ・ト♪ 2008/11/13 14:51 AQUA's .NET 奮闘記

re: 全然ついてイケてない、日曜プログラマのタ・ワ・ゴ・ト♪

タイトル
名前
Url
コメント