Effective C# 6.0
【一休 × bitFlyer】C#を使ったサービス開発の裏側
2017/6/28
宇都宮 諒(@ryo511)
自己紹介
- 宇都宮 諒(うつのみや りょう)
- 株式会社 一休 宿泊事業本部 マーケティング部
- フロントエンドエンジニア
- 得意な言語ベスト3
- PHP, JavaScript, C#
- 仕事でよく書く言語ベスト3
- JavaScript, VB.NET, C#
今日はC#の
お話をします
Effective C# 4.0
- C#を書く上でのベストプラクティスが詰まった名著
- 全50項目
- 邦訳はC#4.0版まで(ちょっと古い)
Effective C# 6.0
- C# 6.0対応!
- 4.0 => 6.0で、全体の3分の1が入れ替え
- 原著の出版は2016年12月
- 未邦訳(2017年6月現在)
- C# 7.0に対応した『More Effective C#』の第2版も2017年8月に発売予定
(全部は無理なので)
C# 6.0 版で追加された項目を5個紹介します!
※各項目の頭にある数字は
Effective C# 6.0における項目番号です
01. varの使用を推奨する(1)
// こちらでもいいけど
string foo = "foo";
// こっちの方がおすすめ
var foo = "foo";
- varキーワードによるローカル変数の型推論を使用する
01. varの使用を推奨する(2)
- 明示的な型指定に起因するバグ
public IEnumerable<string> FindCustomersStartingWith(string start)
IEnumerable<string> q = from c in db.Customers
select c.ContactName;
var q2 = q.Where(s => s.StartsWith(start));
return q2;
}
- ↑のコードはSQLのWHERE句を使って顧客を絞りこむことを想定している
- しかし、実際には以下のように動作する
- 1. 全ての顧客のデータをDBから取得
- 2. Queryable => Enumerableに型変換
- 3. Enumerable.Where()で絞り込み
01. varの使用を推奨する(3)
- varによる型推論の活用
public IEnumerable<string> FindCustomersStartingWith(string start)
var q = from c in db.Customers
select c.ContactName;
var q2 = q.Where(s => s.StartsWith(start));
return q2;
}
- 1. qにはQueryableが入る
- 2. Queryable.Where()が実行される
- 3. WHERE句付きのSQLが実行される
01. varの使用を推奨する(4)
- 明示的に型指定すべき場合もある
var f = GetMagicnumber();
var total = 10 * f / 6; // totalは6.666... だが、切り捨てられて6になる
int GetMagicNumber()
{
return 4;
}
double f = GetMagicnumber();
double total = 10 * f / 6;
- int, double等の数値型は明示的に型を宣言した方が安全
02. 補完文字列を使用する
- 補完文字列(Interpolated Strings)とは?
var foo = "foo";
var bar = "bar";
// こっちでもいいけど
var sf = string.Format("{0}{1}", foo, bar);
// こっちの方がオススメ
var is = $"{foo}{bar}";
// {}の中には式を書ける
var ex = $"{GetString()}";
- string.Format()よりも、短く書けて、わかりやすい
06. nameof演算子を使用する
- ローカル変数の名前を文字列で書いてしまうことがありますよね
public static void DoSomething(object thisCantBeNull)
{
if (thisCantBeNull == null)
throw new ArgumentException("thisCantBeNull");
}
- nameof演算子を使うとローカル変数の名前を取得できます
public static void DoSomething(object thisCantBeNull)
{
if (thisCantBeNull == null)
throw new ArgumentException(nameof(thisCantBeNull));
}
08. null条件演算子(1)
- イベントハンドラの呼び出しをスレッドセーフに書く
public class EventSource
{
public EventHandler<int> Updated { get; set; }
public void RaiseUpdates()
{
_counter++;
var handler = Updated;
if (handler != null)
handler(this, _counter);
// 以下のコードではダメ(スレッドセーフではない)
// if (Updated != null)
// Updated(this, _counter); // Updated がnullになってるかも
}
private int _counter;
}
- ちょっと冗長…
08. null条件演算子(2)
- null条件演算子はスレッドセーフ!
public class EventSource
{
public EventHandler<int> Updated { get; set; }
public void RaiseUpdates()
{
_counter++;
Updated?.Invoke(this, _counter);
}
private int _counter;
}
27. yield returnを使う(1)
- 古典的なコード
public static List<char> GetAlphabetList()
{
var letter = 'a';
var charList = new List<char>();
while (letter >= 'z')
{
charList.Add(letter);
letter++;
}
return charList;
}
- ループが100万回回れば、100万要素のリストが作成されてしまう
27. yield returnを使う(2)
- yield returnを使う
public static IEnumerable<char> GenerateAlphabet()
{
var letter = 'a';
while (letter >= 'z')
{
yield return letter;
letter++;
}
}
- 要素が要求されるごとに生成されるので、メモリ効率が良い
まとめ
- EffectiveなC#を書くための原則
- 1. 最新の.NET Frameworkを使用する
- 2. 言語の新機能を使用する
- 新しい機能は、従来の問題点を修正していることが多い
- 3. 実行環境のリソース管理を理解する
- 例外処理はコストが高いとか、ボックス化が発生するとパフォーマンスが低下するとか
ご清聴ありがとう
ございました
Effective C# 6.0
By Ryo Utsunomiya
Effective C# 6.0
【一休 × bitFlyer】C#を使ったサービス開発の裏側(2017/06/28)
- 2,635