More Related Content
PDF
PDF
Unity開発で使える設計の話+Zenjectの紹介 PDF
PPT
PDF
PDF
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する PDF
PDF
What's hot
PDF
PPTX
MVPパターンによる設計アプローチ「あなたのアプリ報連相できてますか」 PDF
Dockerfileを改善するためのBest Practice 2019年版 PPTX
ネットストーカー御用達OSINTツールBlackBirdを触ってみた.pptx ODP
PDF
20分くらいでわかった気分になれるC++20コルーチン PDF
PPTX
PDF
NextGen Server/Client Architecture - gRPC + Unity + C# PDF
【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう PDF
コンテナの作り方「Dockerは裏方で何をしているのか?」 PPTX
PHP と SAPI と ZendEngine3 と PDF
C#次世代非同期処理概観 - Task vs Reactive Extensions PDF
Unityによるリアルタイム通信とMagicOnionによるC#大統一理論の実現 PDF
History & Practices for UniRx UniRxの歴史、或いは開発(中)タイトルの用例と落とし穴の回避法 PDF
PDF
PDF
PPTX
Using or not using magic onion ODP
Goのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考える Viewers also liked
PDF
Reactive Extensionsで非同期処理を簡単に PDF
ZeroFormatter/MagicOnion - Fastest C# Serializer/gRPC based C# RPC PDF
What, Why, How Create OSS Libraries - 過去に制作した30のライブラリから見るC#コーディングテクニックと個人OSSの... PDF
PDF
「黒騎士と白の魔王」gRPCによるHTTP/2 - API, Streamingの実践 PDF
【Unite 2017 Tokyo】「黒騎士と白の魔王」にみるC#で統一したサーバー/クライアント開発と現実的なUniRx使いこなし術 PPTX
PPTX
PPTX
ASP.NET Core のお気に入りの機能たち (docker向け) PDF
Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例 PDF
Photon Server Deep Dive - PhotonWireの実装から見つめるPhotonServerの基礎と応用 PPTX
Clash of Oni Online - VR Multiplay Sword Action PDF
ZeroFormatterに見るC#で最速のシリアライザを作成する100億の方法 PPTX
RuntimeUnitTestToolkit for Unity PDF
【Unity道場スペシャル 2017札幌】最適化をする前に覚えておきたい技術 -札幌編- Similar to 基礎からのCode Contracts
PPTX
PPTX
PDF
PPTX
PDF
PPTX
PPTX
PDF
PPTX
メタな感じのプログラミング(プロ生 + わんくま 071118) PDF
Effective JavaScript Ch.1 PDF
C#の新機能勉強会 ~ C#7、8の新機能を活用して速く安全なプログラムを書こう~ PPTX
C# 8.0 Preview in Visual Studio 2019 (16.0) PDF
C# コーディングガイドライン 2013/02/26 PDF
C#coding guideline その2_20130325 PPTX
C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~ PDF
Async design with Unity3D PPTX
PDF
traceur-compilerで ECMAScript6を体験 PDF
PDF
More from Yoshifumi Kawai
PDF
A quick tour of the Cysharp OSS PDF
A Brief History of UniRx/UniTask, IUniTaskSource in Depth PDF
Building the Game Server both API and Realtime via c# PDF
ライブラリ作成のすゝめ - 事例から見る個人OSS開発の効能 PDF
Unity C#と.NET Core(MagicOnion) C# そしてKotlinによるハーモニー PDF
Implements OpenTelemetry Collector in DotNet PDF
Deep Dive async/await in Unity with UniTask(EN) PDF
The Usage and Patterns of MagicOnion PDF
True Cloud Native Batch Workflow for .NET with MicroBatchFramework PDF
Memory Management of C# with Unity Native Collections PDF
Deep Dive async/await in Unity with UniTask(UniRx.Async) PDF
PPTX
RuntimeUnitTestToolkit for Unity(English) PDF
How to make the Fastest C# Serializer, In the case of ZeroFormatter PDF
Photon Server Deep Dive - View from Implmentation of PhotonWire, Multiplayer ... PDF
LINQPad with LINQ to BigQuery - Desktop Client for BigQuery PDF
History & Practices for UniRx(EN) PDF
Introduction to NotifyPropertyChangedGenerator 基礎からのCode Contracts
- 1.
- 2.
Profile
Twitter
=> @neuecc
Blog => http://neue.cc/
HNは"neuecc" 読むときは“のいえ”で
ドメン繋いだだけで特に意味はなく発音不能のた
め(ccは声に出しにくいのでスルーという適当対応)
Microsoft
MVP for Visual C#(2011/4-)
公開してるラブラリとか
linq.js
DynamicJson
Chaining Assertion
DbExecutor <- (ちょっとだけ)Code Contracts使った
- 3.
- 4.
- 5.
何か動かないよ?
よくあるnullチェックをしてみようと思った
Contract.Requiresは事前条件
引数がnullだったら契約違反という感じにしたい
static void Hoge(string arg)
{
Contract.Requires(arg != null);
}
が、実行しても無反応
Conditional属性がついているのでコンパル時に
消える(条件付きメソッド、DEBUGとかでお馴染み)
条件はCONTRACTS_FULL(但し自分で足す意味はない)
- 6.
何か動かないよ? Part2
よくあるnullチェックをしてみようと思った again
Contract.Requires<TException>も事前条件
引数がnullだったら契約違反で例外ぶん投げたい
static void Hoge(string arg)
{
Contract.Requires<ArgumentNullException>(arg != null);
}
が、変なゕサートが飛ぶ
そしてゕプリは強制終了
リラターがmustだと?
- 7.
つまるところ
Code Contractsの利用にはリラターが必要
最終的な配布物はコンパラオプションで契約用コードを
取り除く。従って実行効率にも影響しない。
http://ja.wikipedia.org/wiki/契約プログラミング
契約は取り除かれなければならない
そのためにはラブラリだけでは不可能で、コン
パル時にバナリを弄る必要がある
契約の実現のため、現状はバナリ改変している
真に標準搭載されたと言えるのはリラターがコン
パラと統合された時かもね
- 8.
Code Contractsの構成物
必須
Contractクラスなどコードに記述するマーカー
.NET 4で現状標準搭載されているのはこれだけ
バナリリラター(ccrewrite.exe)
オプション
参照ラブラリ生成(ccrefgen.exe)
ドキュメント生成(ccdocgen.exe)
静的チェッカー(cccheck.exe)
cccheckはPremium Editionのみ
静的チェックなしの場合は、例外orゕサートを投げる実
行時チェックという形になる
- 9.
- 10.
Code Contractsのンストール
DevLabs: Code Contracts
http://msdn.microsoft.com/en-us/devlabs/dd491992.aspx
Standard Edition (Visual Studio Professional)
ccrewrite, ccrefgen, ccdocgen
Premium Edition (Visual Studio Premium,Ultimate)
Standard + cccheck
Visual
Studio Express Editionでは使えない
静的チェッカーの有無も大きなところ
契約の正しさが実行時じゃないと確認出来ないとい
うのは、何が正しいのか分からない初学者にとって
学習が困難になる
- 11.
プロジェクトのプロパテゖ
Contractsタブが追加されてる
に、Code
チェックボックスをオンにすると各機能が有効に
パラメータがいっぱいあって困る?
マニュゕルを見れば勿論、説明がある
日本語で?zeclさんのスラドを見よう!
http://d.hatena.ne.jp/zecl/20110213/p2
- 12.
事前条件
Contract.Requires
無印と<TException>とEndContractBlockの三種
無印はコンパラ生成のContractExceptionを投げる
コンパラ生成なので型判別したcatchは不可能
<TE>の場合は指定した例外を投げる
EndContractBlockはif-then-throwを<TE>に変換する
// これと
if (arg == null) throw new ArgumentNullException("arg");
Contract.EndContractBlock();
// これは大体等しい
Contract.Requires<ArgumentNullException>(arg != null);
- 13.
事前条件の違い
EndContractBlockはレガシー環境用
バナリリラターがある環境が前提なら不要
Assembly Modeの選択
Requires, Requires<TE>はStandard Contract
EndContractBlockを使う場合はCustom Parameter
無印と<TE>ではリラト時に残るレベルが違う
無印の場合はReleaseRequiresでは除去される
DebugはFull、ReleaseではPreまたはReleaseを推奨
- 14.
事後・不変・ンターフェス
事後 : Contract.Ensures
戻り値を表すContract.Result<T>とセットで使うこと
が多い
不変 : Contract.Invariant
ContractInvariantMethod属性とセットで
cimコードスニペットを使えば展開される
ンターフェスへの契約
書くのがヘンテコで面倒くさい
cintfコードスニペットを使えば展開される
- 15.
- 16.
動かしたけど嬉しさ少なめ?
静的チェッカなしだと、どうも地味
Premiumの人なら関係ないですねShit!
そんな物足りなさを感じるゕナタにVisualな贈り物
VS拡張:Code Contracts Editor Extensions
http://visualstudiogallery.msdn.microsoft.com/85f0aa38
-a8a8-4811-8b86-e7f0b8d8c71b
契約がIntelliSenseに表示される!
FreeなのでVS Professionalの人でもOK
- 17.
- 18.
- 19.
- 20.
- 21.
嬉しいこと1
引数名を文字列で指定しなくてもいい
リラターが埋め込んでくれるから
コードスニペットcrenは文字列指定付きだけど、個
人的にはそれは不要だと思う
// この文字列で引数名を書くのがかなりヤだった
if (arg == null) throw new ArgumentNullException("arg");
// それをCode Contractsではこう書き、そしてこれは
Contract.Requires<ArgumentNullException>(arg != null);
// バナリリラト後にこうなる
// 最後の"arg != null"がメッセージで、
// 条件を文字列として生成してくれているのが分かる
__ContractsRuntime.Requires<ArgumentNullException>(
arg != null, null, "arg != null");
- 22.
嬉しいこと2
ンターフェスに契約すると、それを実装する
ものへは何も書かなくても自動で埋め込まれる
// こうしてンターフェスへの契約を作ると(cintfスニペット推奨)
[ContractClass(typeof(IHogeContract))]
public partial interface IHoge
{
void Show(string arg);
}
[ContractClassFor(typeof(IHoge))]
abstract class IHogeContract : IHoge
{
public void Show(string arg)
{
Contract.Requires<ArgumentNullException>(arg != null);
}
}
- 23.
それはとっても嬉しいなって
class ClassA :IHoge
{
// 何も書いていませんが
// Contract.Requires<ArgumentNullException>(arg != null)が埋めこまれる
public void Show(string arg)
{
Console.WriteLine(arg);
}
}
class ClassB : IHoge
{
// 全てのメソッドにif(arg == null) throwを書く時代さようなら!
public void Show(string arg)
{
Console.WriteLine(arg + arg);
}
}
これにより、積極的なンターフェスの抽出と
契約の記述が促されます(不純動機ドリブン)
- 24.
嬉しいこと3
静的チェッカーでTester-Doerパターンを安全に
// こんなどうでもいいクラスがあるとして
publicclass ToaruClass
{
int value;
public bool IsReadOnly { get; private set; }
public void SetValue(int value)
{
Contract.Requires(!IsReadOnly);
this.value = value;
}
}
var toaru = new ToaruClass();
// IsReadOnlyをチェックしていないのでunproven
toaru.SetValue(100);
// こう書けばSafe
if (!toaru.IsReadOnly) toaru.SetValue(100);
- 25.
Requiresの基本
Requiresで検証する要素は外部から見えないと、バ
ナリリラターを通りません
public class ToaruClass
{
int value;
private bool isReadOnly;
public ToaruClass(bool isReadOnly)
{
this.isReadOnly = isReadOnly;
}
public void SetValue(int value)
{
// isReadOnlyが外から不可視なのでダメ
Contract.Requires(!isReadOnly);
this.value = value;
}
}
- 26.
- 27.
Requiresの基本 Part2
Requires内で使えるメソッドはPureなもののみ
警告なので実行は出来なくはない
// Pureを付けないと警告が!
[Pure]
public static bool IsNull(string arg)
{
return arg == null;
}
public void Hoge(string arg)
{
Contract.Requires(!IsNull(arg));
}
Pure、つまり副作用ナシということ
String.IsNullOrEmptyなど当然Pure属性ついてます
Pureかどうかは自己申告制だったり(非Pureなもので
も付けること自体は可能、勿論それはダメですよ)
- 28.
嬉しくないこと
静的チェッカーは契約の連鎖で成り立っているの
で、契約されてないラブラリが混じると警告祭
りになって鬱陶しい
そういう場合はContract.Assumeで、契約済みを擬
態していくのだけど数が多いと心が折れる、だけ
じゃなくコードが汚れて可読性悪化の一方に
Typeの一部とかExpressionの一部とか、契約済みの
はずの標準ラブラリの中にも上手く動かないの
がチラホラ
- 29.
例えばこんなunproven
// これは静的チェッカでunproven行き
var func= typeof(Func<,>);
var genFunc = func.MakeGenericType(typeof(int), typeof(int));
// 警告を元に、こうAssumeすればいいんですがなんというかかんというか
var func = typeof(Func<,>);
Contract.Assume(func.IsGenericTypeDefinition);
Contract.Assume(func.GetGenericArguments().Length == 2);
var genFunc = func.MakeGenericType(typeof(int), typeof(int));
- 30.
Unproven Hell
// (objectx) => (object)((T)x).name
static Func<object, object> CreateGetValue(Type type, string name)
{
Contract.Requires<ArgumentNullException>(type != null);
Contract.Requires<ArgumentNullException>(name != null);
// Expression.Unboxに事後条件非nullの契約がないため
// Expression.PropertyOrFieldの引数が求めるrequires expr != null の検証に失敗する
var x = Expression.Parameter(typeof(object), "x");
var func = Expression.Lambda<Func<object, object>>(
Expression.Convert(
Expression.PropertyOrField(
(type.IsValueType)
? Expression.Unbox(x, type)
: Expression.Convert(x, type),
name),
typeof(object)),
x);
return func.Compile();
}
- 31.
どういうこと?
Expressionも基本的には契約されているんですが、
Expression.UnboxとかExpression.Assignと
か、.NET4で新しく追加されたものはあまり契約さ
れてないみたい
なので山崎春のunproven祭り
Expressionは基本的に引数に突っ込んで式としてツ
リー上に組み立てていくものなので、Assumeする
のが難しい
もしAssumeするなら、全部バラして変数にしてから
組み立てなければならないけど、それはない
- 32.
- 33.
- 34.
その他
.NET4標準に入っているContractsラブラリの他に、
幾つか追加の属性がC:¥Program Files
(x86)¥Microsoft¥Contracts¥Languages¥CSharp に
ある(.csフゔルぽん置き)
使い方の詳細はマニュゕルに載ってる
Microsoft
Researchで開発されている自動パラメタ
ラズドテストPexに対してContractsが記述されて
いると、有効な自動生成パラメータが生成できる
ようになる
http://research.microsoft.com/en-us/projects/pex/
- 35.
まとめ
メリットを幾つかあげましたが、忘れてはならな
い基本的なことは、「事前・事後・不変」の契約
が出来るということ
でも、堅苦しい理屈だけじゃなく、目で見て分か
る実用的な便利さを提供してくれるのはいいね!
if-then-throwを撲滅してくれるというだけでも十
分嬉しいなって
まずはそこからで、徐々に高度にステップゕップ
すればいいんじゃないかな
Expressで使えないのが痛い&Premium以上でない
と静的チェッカーが使えないのが大変痛いので、
将来は何とかして欲しいと切実に願う