Your SlideShare is downloading. ×
C#の書き方
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

C#の書き方

4,643
views

Published on


0 Comments
6 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
4,643
On Slideshare
0
From Embeds
0
Number of Embeds
6
Actions
Shares
0
Downloads
33
Comments
0
Likes
6
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. C#C#らしくC#を書こう
  • 2. 自己紹介 岩永 信之 ぐぐれ このサイトの中の 人
  • 3. テーマ 「C#らしいコードの書き方」というテーマを頼まれ ています その前にアンケート  経歴  プログラミング自体経験が浅い人?  C++? Java?  Flash/ActionScript? LAMP系、LLな人?  開発系じゃないけども聞きに来た?  今  Unity? ASP.NET?  その他 C#?  今C#使ってるわけじゃないけど聞きに来た?
  • 4. C#らしい? C#だからというわけじゃないけども  ソースコード/ライブラリ/アプリの依存関係 他の言語から移ってきた人が戸惑うところ  イベント  LINQ Visual Studioに頼ったコーディング  リファクタリング  クラスやメソッドの生成  テスト自動化
  • 5. 前振り: コードの依存関係 依存関係は一方通行に特定のフレームワークへの依存は尐なく
  • 6. 依存関係(1) 基本: 依存は尐ないに越したことはない 依存グラフ どっちがいい?
  • 7. 依存関係(2) 基本: 循環依存はダメ class A class B { { B _b; A _a; } } 特に、ライブラリをまたいだ循環依存はダメ ライブラリX ライブラリY class A class B { { B _b; A _a; } }
  • 8. 依存関係(3) 基本: 画面用フレームワークへの依存は極力避ける 循環、ダ メ! ゲーム画面 GameModel ゲームの中核処 理 Unityなどの フレーム ワーク ASP.NET, Silverlight 画面用フレーム などでも同様 ワークへの依存、 ダメ!
  • 9. 依存関係を切りたい理由 移植性  違うフレームワークを対象にしたい  サーバーとクライアントで同じコードを共有したい テストしやすさ  依存関係が複雑になるほどテストが大変  いわゆるprintfデバッグ、ステップ実行デバッグするなら コンソール アプリが一番
  • 10. 事例: 部分的に流用 全部は要らない 例えば山ほどソー スコードがあった として そのうち使いクラ スは1つだけだと して これだけコピー して動くかどう か  依存性 = 付随して、何ファイルのコピーが必要になるか
  • 11. 事例: サーバーとクライアントで同じ処理 サーバーとクライアントで同じ処理をしたいことが  例: 毎秒のように更新したいもの  資源の増加量計算  施設建設の完了判定 毎秒問い合わせる のもコネクション の無駄遣い クライアント サーバー チート対策もある 同じ処理を再実装 ので、クライアン ト側任せにもでき ない
  • 12. 同じ処理は同じコードで 書ければいいけども…  サーバーとクライアントで言語が違う! クライアント サーバー Flash/ActionScript, 違う PHP, Python, Perl, HTML5/JavaScript‡ Ruby, Java†  でも、C#ならば クライアント サーバー 同じ Unity/C#, ASP.NET/C# Silverlight/C# †クライアントがAndroidならJava使えるけども ‡サーバー側にNode.js使う?
  • 13. コード共有するなら 特定のフレームワークに依存しない書き方を クライアント サーバー (Unityと (ASP.NET) か) Unityに依存 中核処理 • UnityEngine名前空間 Silverlightに依存 • System.Windows名前空間 UnityにもASP.NETに ASP.NETに依存 も依存したくない • System.Web名前空間 この辺りの名前空間のク ラスは、中核処理では使 わない
  • 14. というか、コード共有するなら 特定のフレームワークに依存しない書き方を こいつ クライアント サーバー も (Unityと (ASP.NET) か) こいつもデ バッグ実行遅 中核処理 くない? コンソール ア 単体テスト プリ こっちでデバッグするのが低ストレス
  • 15. 依存切り 依存関係を一方通行にする特定のフレームワークへの依存をなくす
  • 16. 依存を最小限にしたいフレームワーク GUI  Unity、 Silverlight、 ASP.NET(HTML画面を生成) ウェブがらみ  ASP.NET(JSON返すだけとかでも) セキュリティ的に怪しい部分  ファイル読み書きなど 書き込み権限与えていいのか スマホだと、アプリをまたいだファイル共有 認めてない ブラウザーなんかはそもそもファイルアクセ ス無理
  • 17. 依存切りの定石1 フレームワーク依存部分に処理を書かない ビューとかコントローラーとか言わ れる部分
  • 18. フレームワーク依存部分に処理を書かない 例えばUnity 画面側コード(この例だとコントローラー) using UnityEngine; public class CityController : MonoBehaviour Unity依存 { void Update() { こういうところに } ゲームの中核処理を } 書いちゃダメ  コントローラーなら、プレイヤーの入力に応じてモデル を呼ぶだけ  ビューなら、描画などの処理だけ書く
  • 19. フレームワーク依存部分に処理を書かない 例えばASP.NET MVC 画面側コード(この例だとコントローラー) using System.Web; using System.Web.Mvc; namespace MvcApplication1.Controllers { public class HomeController : Controller ASP.NET依存 { public ActionResult Index() { こういうところに } ゲームの中核処理を } 書いちゃダメ }
  • 20. 依存切りの定石2 インターフェイスやデリゲートを利用
  • 21. インターフェイスやデリゲートを使った依存切り 循環依存をなくすための定石 class A class B { { B _b; A _a; } } class A class B : IB { { IB _b; A _a; } } C#の場合はデリゲート interface IB 一方通行に (関数ポインターみたいなもの) { を使うことも多い。 }
  • 22. インターフェイスやデリゲートを使った依存切り 例: いわゆるprintfデバッグ  Unityの場合、UnityEngine.Debugクラスを利用 ログの出力先 中核処理側(Unityに依存したくない) を public class Debug 外部から与え { る public static Action<string> Logger { get; set; } public static void Write(string message) { if (Logger != null) Logger(message); } } 画面側(Unityを利用) Models.Debug.Logger = UnityEngine.Debug.Log;
  • 23. インターフェイスやデリゲートを使った依存切り 例: いわゆるprintfデバッグ  Unityの場合、UnityEngine.Debugクラスを利用 ちゃんと一方通 行 ゲーム画面 ゲームの中核処理 • Models.Debugクラ ス Unity • UnityEngine.Debugクラ ここに依存関係な ス し
  • 24. イベント他の言語からC#に移ってきた人が戸惑う機能その1オブザーバー パターンを言語構文としてサポート
  • 25. イベント(一般用語として) イベント(処理のきっかけ)が外部からやってくる  例: GUIアプリ GUIフレームワーク (Silverlightなど) 1. イベント登録 2. イベント通知 プレイヤーがボタンを ボタン、押されたよ 押したら教えて アプリのコード
  • 26. イベントの例 例: WPFアプリ(C#、デスクトップ向けGUI) using System; using System.Windows; using System.Windows.Controls; public class Program { [STAThread] static void Main() ボタンが押された時の { イベント登録 処理 var button = new Button { Content = "ここを押せ" }; button.Click += (sender, e) => MessageBox.Show("ようこそ"); var win = new Window { Content = button }; var app = new Application(); app.Run(win); } }
  • 27. イベントの例 Flash使ったことある人なら  addEventListener ボタンが押された時の function myEvent(eventObj:MouseEvent) 処理 { trace("ボタンがクリックされました。"); } myButton.addEventListener(MouseEvent.CLICK,myEvent); イベント登録
  • 28. C#のイベント構文 イベントの登録口を生成  add/removeEventListener相当のものを作ってくれる機能 C#のイベント構文を使った、イベント登録口の作成 public class CityModel { public event Action<Resource> ResourceUpdated; } デリゲートの前にeventキーワードを付 けるだけ 意味合い的にはこれに近い private event Action<Resource> _resourceUpdated; public void AddResourceUpdatedListener(Action<Resource> listener) 登録口 { _resourceUpdated += listener; } public void RemoveResourceUpdatedListener(Action<Resource> listener) 解除口 { _resourceUpdated -= listener; }
  • 29. C#のイベント構文 イベントの登録口を生成  add/removeEventListener相当のものを作ってくれる機能 C#のイベント構文を使った、イベント登録 CityModel _city; void Start() { 登録 _city.ResourceUpdated += _city_ResourceUpdated; } void _city_ResourceUpdated(Resource obj) { // 更新があった時の処理 } 解除は -= で
  • 30. イベントの使いどころ 受け身に処理したいとき  イベントが起きた時にだけ動きたい (イベント駆動型プログラム)  普段は何もせず待機  変化が尐ない(イベントがあまり起きない)とき、効率的
  • 31. 注意: 2タイプのGUIフレームワーク ゲーム系  すごく動く上に、パフォーマンスが求められる  フレーム単位で、入力・描画、全部自前で管理 イベント駆動向 メニュー系 き  ユーザーが何か操作した時にだけ動く  「ユーザー操作」というイベントを起点にして駆動
  • 32. ゲームでもメニューよく使うでしょ カード系ゲームとか、ブラ三的なゲームだと、むし ろメニュー系UIがメイン 一般のゲームでも 例えばRPGでよく見るような画面 C#た ステータ ん ス 装備 レベル 99 アイテム 次のレベルまで 0 パーティ プレイ記 所持金 1,000,000 G 録 設定 プレイ時間30:15:00 イベント駆動向き プレイヤーが何か操 時間経過で変化 作するまで再描画必 (更新頻度は秒単位) 要ない
  • 33. なのでゲームでもイベント駆動 イベント駆動で画面を再描画 モデル側 内政資源、数秒に1回更新す る public class CityModel 更新したとき、イベント発行 { public event Action<Resource> ResourceUpdated; } 画面側 void Start() { _city.ResourceUpdated += _city_ResourceUpdated; } 資源の量が変化したとき だけ再描画処理を動かす
  • 34. LINQ他の言語からC#に移ってきた人が戸惑う機能その2 データ処理を簡単に
  • 35. データ処理 例  IDで検索  条件を満たす要素が1つでもあるかどうか探す  合計値や最大値を計算 要はSQLで書くような処理  サーバー側だとデータベース持って、SQL書けばいいけ ども  データをクライアント側にキャッシュした場合どうす る?  メモリ上に読み込んだデータに対してSQL的な処理
  • 36. LINQ C#は、SQL的なデータ処理が得意  C# 3.0で導入されたLINQ(Language Integrated Query) 例: 顧客データ一覧から、女性客の年齢分布を求める var 女性客の年齢分布 = from c in 顧客一覧 where c.性別 == "女" group c.年齢 by c.年齢 into g orderby g.Key select new { 年齢 = g.Key, 数 = g.Count() }; クエリ式 • SQL的なクエリを書ける • selectが末尾にくるくらいで、かなりSQLその まんま • C#の型をそのまま使える(補完も効く)
  • 37. LINQ C#は、SQL的なデータ処理が得意  C# 3.0で導入されたLINQ(Language Integrated Query) 例: 顧客データ一覧から、女性客の年齢分布を求める var 女性客の年齢分布 = 顧客一覧 .Where(c => c.性別 == "女") .GroupBy(c => c.年齢, c => c.年齢) .OrderBy(g => g.Key) .Select(g => new { 年齢 = g.Key, 数 = g.Count() }); クエリ式の展開結果(メソッドの連鎖になる) • 元のSQL的な句に対応するメソッドがある • 使うためには、System.Linq名前空間を using
  • 38. データ処理のパーツ 条件選択、グループ化、整列、集計、射影 入力 出力 集計 射影 a α b β c グループ 集計 射影 γ d 条件選択 整列 δ 化 ・・・ ・・・ where group by order by 集計 射影 ・ ・・ from select Aggregate, Sum, Countなど  だいたいSQLと一緒
  • 39. 一時リストを作っちゃダメ 例: 偶数だけ選択、二乗を計算 悪い例(一時リストを作成) var results = new List<int>(); foreach (var x in data) { if ((x % 2) == 0) results.Add(x * x); } 良い例(LINQ) var results = data .Where(x => (x % 2) == 0) .Select(x => x * x);
  • 40. サンプル MSDN公式サンプル: 101 LINQ Samples  http://code.msdn.microsoft.com/101-LINQ-Samples- 3fb9811b
  • 41. 補足: 匿名関数 その場限りの関数を作れる var results = data .Where(x => (x % 2) == 0) .Select(x => x * x); こんなんのために、いちいち こんな感じのメソッド作りたくない // x が偶数のとき true // 二乗を計算 static bool IsEven(int x) static int Square(int x) { { return (x % 2) == 0; return x * x; } }  =>(goes to)演算子  引数 => 式
  • 42. 補足: 拡張メソッド LINQのSelectなどは、実は「拡張メソッド」 静的メソッドを、後置き記法で書く機能 本来、こう書く必要がある(実は静的メソッド) var results = Enumerable.Select(data, x => x * x); 拡張メソッドなら 見かけ上、インスタンス メソッド的に書ける(後置き記法にできる) var results = data.Select(x => x * x);  メソッドを連鎖的に書きやすい  Enumerableなどのクラス名を省略できる EnumerableクラスはSystem.Linq名前空間にある
  • 43. 補足: 拡張メソッド LINQのSelectなどは、実は「拡張メソッド」 静的メソッドを、後置き記法で書く機能 拡張メソッドの実装例 public static class Enumerable {第1引数にthis public static IEnumerable<U> Select<T, U>(修飾子を付け this IEnumerable<T> source, る Func<T, U> selector) { foreach (var x in source) { yield return selector(x); } } }
  • 44. Visual Studioに頼ろうライブ コーディングでも見せようかと
  • 45. Visual Studio もちろん、生産性向上のためのツールだけども 学習ツールとしても優秀  まず、Visual Studioの作るテンプレや、補完で出てくる コードを覚えよう デモ  コード スニペット  スマート タグ
  • 46. デモ foreach メソッド抽出 usege-first 単体テスト生成 LINQ
  • 47. サンプル HTMLスクレイピング  http://code.msdn.microsoft.com/C-15Visual-Studio- 5511658e 15パズル  http://code.msdn.microsoft.com/C-2-83b48d3f 東方弾幕風もどき

×