C#と諸々

C#がメインで他もまぁ諸々なブログです
おかしなこと書いてたら指摘してくれると嬉しいです(´・∀・`)
つーかコメント欲しい(´・ω・`)

2006/12/21 20:20
.NET Framework 3.0 がリリースされて少し経ちましたが、僕はまだ WPFにもWCFにもWFにも手を出していませんでした。
でも、最近入ってきた仕事でWCFを使ったWebサービスの開発を行うことになりそうです。
今はWCFの調査段階で、サンプルプログラムの作成中。そして、「そうだ、クライアント側はWPFで作ろう」という素晴らしい名案が浮かびましたので、WPFの調査も ( 勝手に ) 行っています。
WCFとWPFのお勉強を業務の一環としてできるという、なんともラッキーな状況です。 ( まぁ、さすがにWPFの方は深くつっこんで勉強するわけにはいきませんが^^; )

とりあえず、WCFの勉強に使っているサイトと、WPFの勉強に使おうと思っているサイトを貼り付けておきます。

Windows Communication Foundation概説 - @IT

WPF アプリケーションを作る クッキングガイド


あと、↓の辺も抑えておきたいですね。 ( オレが。 )

Windows Communication Foundation アーキテクチャの概要

Windows Communication Foundation による高信頼メッセージングについて

Windows Presentation Foundation - ホーム


.NET Framework 3.0 や、Visual Studio 2005でWPF/WCF開発を行うためのアドインの入手に関しては、こちらの記事を参照してください。

.NET Framework 3.0 正式版 リリース
スポンサーサイト



タグ: .NET C# WPF WCF
2006/12/20 20:06
これから何回かに分けて、リフレクションの基本について一通り解説して行こうかと思います。

【 リフレクションとは何か? 】
一言で言うと、メタデータ ( データについてのデータ ) を扱う仕組みです。

アセンブリ,モジュール,型 ( クラス,構造体,インターフェイス,デリゲート,列挙型 ) ,メンバ (  フィールド,プロパティ,イベント,コンストラクタ,メソッド ) の情報を、動的に取得・使用・生成することができます。
要するに、プログラムコードでプログラムコードを扱うというようなイメージです。
まだイマイチわかりづらいと思いますので、例を挙げて説明していきます。

例えば、 パブリックなメソッド " Method1 " と、プライベートなメソッド " Method2 " を持つ、" Class1 " というクラスがあります。
このクラスに対してリフレクションを利用すると、
「Class1クラスのMethod1メソッドのパラメータリストを、動的に調べる」とか、
「Class1クラスのプライベートメソッドであるMethod2メソッドを、外部から呼び出す」とか、
「Class1クラスに、新しく " Method3 " というメソッドを、動的に追加する」
といったことが可能になります。もちろん、これらは一例であり、他にもいろいろなことができます。

また、アセンブリに埋め込まれたリソースの取得や、アセンブリの動的ロード、属性の取得などにも、リフレクションを利用します。


【 リフレクションを使う場面 】
「リフレクションなんて必要あるの?」と思う人もいるかもしれませんが、例えば以下に挙げるようなアプリケーションやクラスライブラリでは、しばしばリフレクションを必要とします。

・.NET 開発のサポート系アプリケーション
代表例 : Visual Studio、Reflector、NDoc、FxCop、etc...

・.NET 開発のサポート系クラスライブラリ
代表例 : Enterprise Library、etc...

・他者が機能を拡張するための機構 ( プラグイン ) を設けるアプリケーション
代表例 : Visual Studio 2005、etc...

どれも、リフレクションを使用している機能を利用するのは.NET開発者です。 ( " プラグイン機能を利用するのはプラグイン開発者 " として。 )
他に、IronPytonやPowerShellも、リフレクションを利用しています。これらは、コンソールに入力されたコード ( コマンド ) を、リフレクションを利用して処理しています。


【 名前空間 】
リフレクションの主要なクラスは、以下の2つの名前空間に含まれています。

System.Reflection 名前空間
メタデータを動的に取得・使用するためのクラス群が含まれています。

System.Reflection.Emit 名前空間
メタデータを動的に生成するためのクラス群が含まれています。

なお、System.Reflection 名前空間には含まれてはいませんが、Type クラス (System) や、AppDomain クラス (System) も、リフレクションにおける重要なクラスの一つです。



今回はここまでです。次回は、リフレクションを利用してメタデータを取得する方法について解説します。
タグ: .NET C# Reflection
2006/12/20 10:53
もう、公開されてから何日か経っているのですが、一応。

Visual Studio 2005 Service Pack 1


他の方のブログを見ていると、既にいくつかのバグが発見されていますね。
タグ: .NET C#
2006/12/19 14:55
別のPCにリモートデスクトップ接続して、そこからブラウザでバーチャルサーバーにアクセスして、その中で更にブラウザを立ち上げて。。。。。。。。3つのPCを一台で横断、わけがわからなくなってくるな orz 
別PCと仮想サーバーはWindows Server 2003だから、色んな所で認証求めてくるし。
タグ:
2006/12/15 00:41
PowerShell関数は、通常、引数が二つで戻り値の型がvoid型であるデリゲートにしか、キャストすることができません。
ちょっと不便だと感じたので、PowerShell関数を任意のデリゲートにキャストするコマンドレットを作成しました。


【 0. 目次 】
1. Download
2. 解説
3. 使用例


【 1. Download 】
このコマンドレットは、YokoKen.PowerShell.Utilityというスナップインに含まれています。このスナップインは以下の記事にて公開しています。

YokoKen.PowerShell.Utility


【 2. 解説 】
[ 2.1 コマンド名 ]
このコマンドレットには、ConvertTo-Delegateという名前が付けられています。

[ 2.2 概要 ]
ConvertTo-Delegateコマンドレットは、指定したPowerShell関数 ( = ScriptBlockオブジェクト ) を、指定したデリゲートにキャストします。指定できるデリゲートに制限はありません。

[ 2.3 構文 ]
ConvertTo-Delegateコマンドレットの構文は以下のようになっています。

ConvertTo-Delegate [-Target] <System.Management.Automation.ScriptBlock> [-DelegateType] <System.Type> [[-ErrorNotifiedByDialog] <System.Boolean>]


[  パラメータ  ]
・Target <System.Management.Automation.ScriptBlock>
デリゲートにキャストするPowerShell関数を指定します。Targetパラメータに指定できるPowerShell関数に制限はありません。PowerShell関数の戻り値が、DelegateTypeパラメータに指定したデリゲートに定義されている戻り値の型と異なる場合でも、問題なく実行できます。
必須
:  true
位置 : 1
既定値 : -
パイプライン入力を許可する
: true (ByValue)
ワイルドカード文字を許可する : false
Nullを許可する : false

・DelegateType <System.Type>
PowerShell関数をキャストするデリゲートを指定します。DelegateTypeパラメータには、デリゲート ( = MulticastDelegate派生型 ) を指定してください。それ以外では例外が発生します。
必須
: true
位置 : 2
既定値 :  -
パイプライン入力を許可する
: false
ワイルドカード文字を許可する :  false
Nullを許可する :  false

・ErrorNotifiedByDialog <System.Boolean>
デリゲートオブジェクトとして実行されたPowerShell関数が、実行中に例外をスローした時、例外の情報をダイアログで通知するかどうかを指定します。falseを指定した場合は、PowerShellのホストアプリケーションから、通常通りに通知されます。規定値はfalseです。
必須
: false
位置 : 3
既定値 :  false
パイプライン入力を許可する
: false
ワイルドカード文字を許可する :  false
Nullを許可する :  false

[ 2.4 詳細 ]

・デリゲートオブジェクトとして呼び出されたPowerShell関数の引数
デリゲートオブジェクトとして呼び出されたPowerShell関数で、引数を受け取ることができます。ただし、$Args変数から取得する以外の手段で引数を取得することはできません。例えば、以下の例では引数を取得できず、例外が発生します。

[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms");
$form1 = New-Object "System.Windows.Forms.Form";
function form1_Click([object] $sender, [EventArgs] $e)
{
    # デリゲートオブジェクトとして呼び出されると、$senderにはNullが入っています。
    ([System.Windows.Forms.Form]$sender).Text = "Hoge";
}

$clickHandler = ConvertTo-Delegate $Function:form1_Click System.EventHandler;
$form1.Add_Click($clickHandler);
[System.Windows.Forms.Application]::Run($form1);


正しく動作させるには、以下のように記述します。

[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms");
$form1 = New-Object "System.Windows.Forms.Form";
function form1_Click
{
    # デリゲートオブジェクトとして呼び出されても、$Argsの各要素には適切な値が入っています。
    ([System.Windows.Forms.Form]$Args[0]).Text = "Hoge";
}

$clickHandler = ConvertTo-Delegate $Function:form1_Click System.EventHandler;
$form1.Add_Click($clickHandler);
[System.Windows.Forms.Application]::Run($form1);


・デリゲートオブジェクトとして呼び出されたPowerShell関数の戻り値
デリゲートオブジェクトとして呼び出されたPowerShell関数は、以下の条件を満たすことで、戻り値を返すことができます。

条件 : PowerShell関数の戻り値が、キャストしたデリゲートに定義されている戻り値の型にキャストできること。

条件を満たさない場合でも問題なく実行できますが、戻り値はNullとなります。 ( キャストしたデリゲートに定義されている戻り値の型がVoid型の場合は、何も返しません。 )

例えば、以下の例では戻り値はNullとなります。 ( ResolveEventHandlerデリゲートの戻り値の型は、System.Reflection.Assemblyクラスです。 )

# ResolveEventHandlerにキャストして呼び出されたとき、戻り値はNullとなります。
$func1 = ConvertTo-Delegate {"test";} ResolveEventHandler;
$func1.Invoke($(), $());


以下の例のように、PowerShell関数の戻り値が、デリゲートに定義されている戻り値の型にキャストできる場合は、戻り値が返されます。

# ResolveEventHandlerにキャストして呼び出されたとき、戻り値は適切な値となります。
$func1 = ConvertTo-Delegate {[System.Reflection.Assembly]::GetExecutingAssembly();} ResolveEventHandler;
$func1.Invoke($(), $());



【 3. 使用例 】
・イベントハンドラ
以下のコードは、フォームが閉じられる際に、終了確認ダイアログを表示し、「いいえ」が選択された場合に終了をキャンセルさせる例です。 ( コード中で使用しているRun-Formコマンドレットについては、こちらの記事を参照してください。 )

[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms");
$form = New-Object "System.Windows.Forms.Form";
$formClosingHandlScript =
  {
    $sender = [System.Windows.Forms.Form]$Args[0];
    $e = [System.Windows.Forms.FormClosingEventArgs]$Args[1];
    $messageBoxButton = [System.Windows.Forms.MessageBoxButtons]::YesNo;
    $messageBoxIcon = [System.Windows.Forms.MessageBoxIcon]::Question;
    $dialogResult = [System.Windows.Forms.MessageBox]::Show($sender, "終了しますか?", "確認", $messageBoxButton, $messageBoxIcon);
    if ($dialogResult -ne [System.Windows.Forms.DialogResult]::Yes)
    {
      $e.Cancel = $True;
    }
  };

$formClosingHandler = ConvertTo-Delegate $formClosingHandlScript System.Windows.Forms.FormClosingEventHandler;
$form.Add_FormClosing($formClosingHandler);
Run-Form $form;


・Threadクラスによるマルチスレッド
以下の例のように、Threadクラスを用いることで、ThreadStartデリゲートにキャストしたPowerShell関数を別スレッド上で実行させることができます。
ただし、別スレッドでの実行を目的にPowerShell関数をデリゲートにキャストする場合、ErrorNotifiedByDialogパラメータには必ず Trueを指定してください。Trueを指定しないと、別スレッド上でのPowerShell関数の実行中に例外が発生した場合に、例外が適切に処理されないため PowerShellが強制終了してしまいます。

[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms");
$messageBoxClass = [System.Windows.Forms.MessageBox];
$process = ConvertTo-Delegate {[void] $messageBoxClass::Show("test");} System.Threading.ThreadStart $True;
$newThread = New-Object System.Threading.Thread $process;
$newThread.Start();

2006/12/15 00:36
PowerShellで表示させたWindowsフォームを、PowerShellから操作することを可能にするコマンドレットです。


【 0. 目次 】
1. Download
2. 解説
3. 使用例


【 1. Download 】
このコマンドレットは、YokoKen.PowerShell.Utilityというスナップインに含まれています。このスナップインは以下の記事にて公開しています。

YokoKen.PowerShell.Utility


【 2. 解説 】
[ 2.1 コマンド名 ]
このコマンドレットには、Run-Formという名前が付けられています。

[ 2.2 概要 ]
Run-Formコマンドレットは、指定したフォームオブジェクトを、別スレッド上で表示します。別スレッド上で表示されるため、表示中もPowerShellからフォームを操作することができます。

[ 2.3 構文 ]
Run-Formコマンドレットの構文は以下のようになっています。

Run-Form [-Target] <System.Windows.Forms.Form>


[  パラメータ  ]
・Target <System.Windows.Forms.Form>
対象となるフォームオブジェクトを指定します。
必須
:  true
位置 : 1
既定値 : -
パイプライン入力を許可する
: true (ByValue)
ワイルドカード文字を許可する : false
Nullを許可する : false


【 3. 使用例 】
以下の例のコマンドを実行すると、フォームが表示され、PowerShellが入力待機状態となります。

[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms");
$sampleForm = New-Object "System.Windows.Forms.Form";
$helloButton = New-Object "System.Windows.Forms.Button";
$helloButton.Text = "Click";
$helloButton.Location = New-Object "System.Drawing.Point" (50, 50);
$helloButton.Add_Click({[System.Windows.Forms.MessageBox]::Show("Hello Hoge !")});
$sampleForm.Controls.Add($helloButton);

# コマンドレット実行
Run-Form $sampleForm;


フォーム表示後、以下の例のコマンドを実行すると、PowerShellからフォームを操作できることが確認できます。

# フォームを最前面に固定
$sampleForm.TopMost = $True;
# フォームのタイトルを設定
$sampleForm.Text = "Sample Form";
# フォームの不透明度を設定
$sampleForm.Opacity = 0.5;
# フォームの位置を設定
$sampleForm.Location = New-Object "System.Drawing.Point" (0, 0);


フォーム表示後のコントロールの追加は、以下のように、Invokeメソッドを使用して行います。
Invokeメソッドを使用しない場合、エラーとなってしまうので注意してください。
なお、以下の例では、同じスナップインに含まれているConvertTo-Delegateコマンドレットを使用して、PowerShell関数をMethodInvokerにキャストしています。ConvertTo-Delegateコマンドレットに関しては、こちらの記事を参照してください。

$exitButton = New-Object "System.Windows.Forms.Button";
$exitButton.Text = "Exit";
$exitButton.Location = New-Object "System.Drawing.Point" (100, 100);
$exitButton.Add_Click({$sampleForm.Close()});
$sampleForm.Invoke((ConvertTo-Delegate {$sampleForm.Controls.Add($exitButton)} System.Windows.Forms.MethodInvoker))


フォームを閉じる時は、フォームの閉じるボタンから閉じることも、PowerShellから以下のコマンドを実行して閉じることもできます。

# フォームの破棄
$sampleForm.Dispose();
2006/12/15 00:35
スナップインの最終更新日:2006/12/14

自作のPowerShell ユーティリティ コマンドレットをまとめたスナップインです。新しいコマンドレットを作成するたびに、このスナップインに追加していきます。 ( 各コマンドレットの作成日は、コマンドレット一覧を参照してください。 )


【 0. 目次 】
1. Download
2. インストール方法
3. 使い方
4. コマンドレット一覧
5. アンインストール方法


【 1. Download 】
以下のリンクをクリックするとDownloadページへ移動するので、移動先からダウンロードしてください。

YokoKen.PowerShell.Utility.dll ( YKPSUtility.zip )

ソース ( YKPSUtility_src.zip )


【 2. インストール方法 】
[ 2.1 解凍 ]
ダウンロードしたファイル ( YKPSUtility.zip ) を、解凍します。

[ 2.2 配置 ]
PowerShell のインストールフォルダ ( 通常はC:\Windows\system32\windowspowershell ) に、SnapInというフォルダを作成 ( ※1 ) し、解凍されたYokoKen.PowerShell.Utility.dllを置きます。

[ 2.3 インストール ]
以下のコマンドをPowerShellで実行します。

&"$env:windir/Microsoft.NET/Framework/v2.0.50727/InstallUtil.exe" ($PSHome + "\SnapIn\YokoKen.PowerShell.Utility.dll");


※1 : 違うフォルダでも構いませんが、違うフォルダにする場合、 [ 2.3 インストール ] のコマンドで指定するパスもそれに合わせて変更してください。


【 3. 使い方 】
このスナップインを使うには、PowerShellの起動のたびに、以下のコマンドを実行してスナップイン登録する必要があります。

Add-PSSnapin "YokoKen.PowerShell.Utility";




【 4. コマンドレット一覧 】
このスナップインには以下のコマンドレットが含まれています。コマンドレット名をクリックすると、詳細記事に移動します。

Run-Form ( 作成日:2006/12/02 )
Run-Formコマンドレットは、指定したフォームオブジェクトを、別スレッド上で表示します。別スレッド上で表示されるため、PowerShellからフォームを操作することができます。

Convert-Delegate ( 作成日:2006/12/14 )
Convert-Delegateコマンドレットは、指定したPowerShell関数を、指定したデリゲート型にキャストします。指定できるデリゲート型に制限はありません。


【 5. アンインストール方法 】
以下のコマンド ( ※2 ) をPowerShellで実行します。

$deploymentPath = $PSHome + "\SnapIn\YokoKen.PowerShell.Utility.dll";
&"$env:windir/Microsoft.NET/Framework/v2.0.50727/InstallUtil.exe" -u $deploymentPath;
Remove-Item $deploymentPath;


※2 : [ 2.2 配置 ] ,[ 2.3 インストール ] で、違うフォルダにインストールした場合、コマンドで指定するパスをそれに合わせて変更してください。
2006/12/14 10:52
Microsoft,ロボット開発環境「Microsoft Robotics Studio」を提供開始:ITpro

以下、記事の一部を引用 ( MRS = Microsoft Robotics Studio )

 MRSには,ロボット工学機能をシミュレートする3Dツール,各種ハードウエアと互換性のあるサービス指向のランタイム,そしてドラッグ・アンド・ドロップ操作で容易にプログラム可能なビジュアル・プログラミング言語が含まれる。
 同開発環境では,Visual C#,Visual Basic,IronPythonのほか,MRSのサービス・ベースのアーキテクチャに対応したサードパーティ言語を使って,ロボット制御ソフトを開発できる。


ダウンロードはこちらから
Download details: Microsoft Robotics Studio (1.0)


少し前のニュースですが、関連情報です。
Microsoftなど,コンピュータ科学教育にロボット技術を活用する組織「IPRE」を設立:ITpro


タグ: .NET C# IronPython
2006/12/14 10:38
「MSDN オンラインサービス向上のため、10 分 お時間をいただけますか ?」だそうです。
全部で15問の匿名形式アンケートです。

MSDN オンライン ユーザアンケート
タグ: .NET C#
2006/12/07 23:00
2006年12月11日発売です。 ( MSのニュースレターには12日って書いてあるけど ^^; )

プログラミング Microsoft .NET Framework 第2版

MCP等の資格保有者は、 日経BPソフトプレス/MTCこのページ から申し込むと、10% OFFで購入できます。 ( サインインしてからじゃないとダメですよ。 )


かなり濃いですよ。
.NET 開発者なら、必ず読むべきです。
タグ: .NET C# CLR 書籍
2006/12/07 20:37
メモです。。

XmlSerializer クラス (System.Xml.Serialization)
オブジェクトとXMLのシリアライズ・デシリアライズを行うクラス。
シリアライズの対象はパブリックフィールドとパブリックプロパティのみ。

XmlRootAttribute クラス (System.Xml.Serialization)
型 ( クラス、構造体、列挙体、インターフェイス ) に対して、XMLルート要素名を明示的に指定するための属性。

XmlElementAttribute クラス (System.Xml.Serialization)
メンバー ( パブリックフィールド、パブリックプロパティ ) に対して、XMLの要素としてシリアライズされることを明示的に指定するための属性。 要素名を明示的に指定することも可能。
また、コレクションメンバーに対して、引数なしでこの属性を付加すると、そのコレクションの各要素がXML要素のシーケンスとして認識される。

XmlAttributeAttribute クラス (System.Xml.Serialization)
メンバー ( パブリックフィールド、パブリックプロパティ ) に対して、XMLの属性としてシリアライズされることを明示的に指定するための属性。 属性名を明示的に指定することも可能。

XmlIgnoreAttribute クラス (System.Xml.Serialization)
メンバー ( パブリックフィールド、パブリックプロパティ ) に対して、シリアライズの対象としないことを明示的に指定するための属性。

XmlArrayItemAttribute クラス (System.Xml.Serialization)
派生型を含む可能性のあるコレクションメンバーに対して、含まれる可能性のある型を明示的に指定することで、正常にシリアライズできるようにするための属性。


コレクションは以下の条件を満たすことでシリアライズ可能となる。

引用
XmlSerializer は、IEnumerable または ICollection を実装するクラスは特別に対処します。IEnumerable を実装するクラスは、1 つのパラメータを受け取るパブリックな Add メソッドを実装している必要があります。Add メソッドのパラメータは、GetEnumerator から返された値の Current プロパティから返された型と同じであるか、またはその型の基本型の 1 つであることが必要です。IEnumerable に加えて ICollection (CollectionBase など) を実装しているクラスは、整数を受け取るパブリックな Item インデックス付きプロパティ (C# のインデクサ) および整数型のパブリック Count プロパティを持っている必要があります。Add メソッドのパラメータは、Item プロパティから返された型か、その型の基本型の 1 つと同じ型であることが必要です。ICollection を実装するクラスの場合、シリアル化する値は GetEnumerator を呼び出して取得するのではなく、インデックス付き Item プロパティから取得します。



XML スキーマ定義ツール (Xsd.exe)
XMLスキーマからクラスの生成、XMLスキーマからDataSetの生成、クラスからXMLスキーマの生成、などを行うツール。


[ 参考 ]
@IT:連載:.NETで簡単XML
タグ: .NET C# XML
2006/12/07 11:03
ファーストサーバ Windows DOTNET レンタルサーバ にて、ASP.NET 2.0 & SQL Server 2005 が使える無料レンタルサーバーサービス「FS デベロッパーズ プラットフォーム エクスプレス2」の提供が開始されました。

主な機能
・独自ドメインを取得できる。
・サーバーはMicrosoft Windows Server 2003 R2 日本語版。
・ASP.NET 2.0 or 1.1、SQL Server 2005 日本語版、AJAX 1.0 Beta2が利用可能。
・Web容量 100MB
・DB容量 100MB

注意点
・商用利用はできない。
・商用利用した場合、サーバー設定が削除される。
・定期的にファーストサーバから送られてくるアンケートに回答する必要がある。
・アンケートに対して指定期日以内に回答しなかった場合、サーバー設定が削除される。
・3ヶ月間FTPアクセスがない場合、サーバー設定が削除される。

タグ: .NET C# ASP.NET
2006/12/06 15:53

2007/02/25 追記

この記事に書いたことは、現在の私の意見とは異なります。

現在は、業務エラーは例外で表すべきと私は考えています。
詳細はこちらの記事を参照してください。


以前書いた業務エラーの表現方法ついての考察。
経験不足が否めない。。。
つっこみしてくれる方大募集!w

【 業務エラーの定義 】
まず、Application Architecture for .NET第三章 ( 以下、AAfN ) と、書籍 「 Microsoft Visual Studio 2005 による Webアプリケーション構築技法 」 ( 以下、赤間本 ) での、業務エラーの定義に差異はないか?

[ AAfN ]
AAfNでは、例外を以下のように分類している。

技術上の例外
データベース接続の失敗など。

業務上の例外
外部キー制約の違反など。

[ 赤間本 ]
赤間本では、例外を以下のように分類している。

アプリケーション/システムエラー
( 例として、 ) データベース障害やネットワーク障害により、データベースの読み書きが行えなかった場合。

業務エラー
( 例として、 ) 希望された顧客IDがすでに他の顧客により利用されていたといった理由により、顧客情報が登録できなかった場合。

また、赤間本では、業務エラーとアプリケーション/システムエラーの切り分け方として、「業務設計の中で想定されていなければならないケースが業務エラー」というようなことも書かれている。

[ 比較 ]
AAfNは外部キー制約の違反、赤間本は一意キー制約の違反を例に挙げている。これらは、「他のユーザーが既に登録/編集済み」などが原因で発生する。
どちらもあまり詳細には書かれていないが、定義の差異はなさそうだ。
個人的には、「エンドユーザーに許容されている範囲内での、エンドユーザーの操作 ( 入力 ) 次第で発生しうる、正常系でないフローが業務エラー」で、「システム異常など、まさに例外的な状況がアプリケーション/システムエラー」だと解釈している。


【 戻り値と例外 】
業務エラー云々を抜きにして、戻り値と例外について分析してみる。

[ 戻り値 ]

与えられた入力 ( 引数 ) に操作を適用した結果生じる出力。
引数と違い、返せるオブジェクトは一つだけ。
固定の型。
戻り値は呼び出し元でしか受け取れない。

[ 例外 ]
操作の途中で、例外的な状況に陥った場合に、通常とは異なるフローで、その例外情報を上位に伝播する。
例外メッセージ、スタックトレース、例外の元となった例外など伝播される情報が多い。
例外そのものは、例外の分類に応じた型 ( Exception派生クラス ) となる。
例外は例外ハンドラで処理する。その際、捕らえる例外を限定することができる。
スローされた例外は、対応する例外ハンドラが現れるまで上位に伝播される。
特殊な情報伝播を行うため、コストが高い。


【 業務エラーの表現方法の分析 】

[ 業務エラーの内容 ]
どのような業務エラーが発生したのかを知る必要はあるか?
これは、「ある」と思う。
DBの制約に関する業務エラーを例に挙げると、「IDが重複 ( 一意キー制約に違反 ) しているのか?」、「削除されたアイテムを参照 ( 外部キー制約に違反 ) しているのか?」、「違反している場所はどこなのか?」といった情報は、どこを修正すればいいのかが明確になり、有益である。

・業務エラーを例外で表した場合
ExceptionのMessageプロパティに、どのような業務エラーが発生したのか記述することができる。

・業務エラーを戻り値で表した場合
戻り値の型がBoolean型だと、どのような業務エラーが発生したのかは不明となる。ただし、業務エラーが一つの理由でしか発生しない場合は、Boolean型でも明確となる。また、チェック系メソッドを用意して事前にチェックを行えるようにしておけば、業務エラーの内容を知ることができる。
また、戻り値の型を、Boolean型ではなくEnum型にすれば、業務エラーに応じた戻り値を返せる。

[ スタックトレース ]
業務エラーを例外で表した場合は、スタックトレースが利用できるが、スタックトレースは必要か?
これは、「不要」である。そもそも業務エラーは「設計時に想定されている状況」なのだから、スタックトレースなんて見る必要がない。

[ 上位での処理方法 ]
先に述べたように、戻り値は呼び出し元でしか受け取れない。例外は、対応する例外ハンドラが現れるまで上位に伝播される。
最上位に例外ハンドラを用意するだけで済むので、例外の方に分があるように思える。

【 考察 】
一見すると、戻り値の方が処理がめんどうで、例外に分があるように見える。
しかし、業務エラーの内容を伝えるのにExceptionのMessageプロパティを使うのは、あまり適 切ではないように思う。GUIに表示するメッセージを下位層で決めているようなものだ。業務エラーは文字通り「業務」上のエラーなので、表示・表示内容の 責任を持つのはGUIである。しかも、文字列なので、上位層の「プログラムコード」で業務エラーの詳細を判別できない。 ( 各業務エラーごとにExceptionクラスを定義したり、独自のプロパティなんかを用意してやればなんとかなりそうだけど。 )
そもそも、業務エラーは設計時に想定されている事象なので、例外的な状況ではない。 ( という話をどこかで聞いた。 )


【 結論 】
「業務エラーは戻り値で表現」です。
タグ: .NET C# 例外処理
2006/12/02 03:00


この記事で公開しているファイルは、古い形式となっております。
今後は、全ての自作コマンドレットを、「YokoKen.PowerShell.Utility.dll」として、こちらの記事で公開します。




PowerShellで表示させたWindowsフォームを、PowerShellから操作したい・・・!
ってことで、そんなコマンドレットを作ってみた。

1. Download
2. インストール方法
3. 使い方
4. 使用例


【 1. Download 】
以下のリンクをクリックするとDownloadページへ移動するので、移動先からダウンロードすること。

YokoKen.PowerShell.Forms.dll ( YKPSForms.zip )

ソース ( YKPSForms_src.zip )


【  2. インストール方法 】
[ 2.1 解凍 ]
ダウンロードしたファイル ( YKPSForms.zip ) を、解凍する。

[ 2.2 配置 ]
PowerShellのインストールフォルダ ( 通常はC:\Windows\system32\windowspowershell ) に、SnapInというフォルダを作成 ( ※1 ) し、解凍されたYokoKen.PowerShell.Forms.dllを置く。

[ 2.3 インストール ]
以下のコマンドをPowerShellで実行する。

&"$env:windir/Microsoft.NET/Framework/v2.0.50727/InstallUtil.exe" ($PSHome + "\SnapIn\YokoKen.PowerShell.Forms.dll");


※1 : 違うフォルダでも構わないが、違うフォルダにする場合、 [ 3. インストール ] のコマンドで指定するパスもそれに合わせて変えること。


【 3. 使い方 】
[ 3.1 スナップイン登録 ]
このコマンドレットを使うには、PowerShellの起動のたびに、以下のコマンドを実行してスナップイン登録する必要がある。

Add-PSSnapin "YokoKen.PowerShell.Forms";


[ 3.2 Run-Formコマンドレット ]

YokoKen.PowerShell.Formsには、Run-Formという名前のコマンドレットが用意されている。スナップイン登録を行うと、このRun-Formコマンドレットが使用可能になる。
以下は、Run-Formコマンドレットの構文。

Run-Form [-target] <System.Windows.Forms.Form>


Run-Formコマンドレットは、targetパラメータに指定したフォームオブジェクトを、別スレッド上で表示する。別スレッド上で表示されるため、PowerShellからフォームを操作することができる。


【 4. 使用例 】
こんな感じ。

# スナップイン登録
Add-PSSnapin "YokoKen.PowerShell.Forms";
# System.Windows.Forms.dllのロード
[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms");

# サンプルフォーム作成
$sampleForm = New-Object "System.Windows.Forms.Form";
$helloButton = New-Object "System.Windows.Forms.Button";
$helloButton.Text = "Click";
$helloButton.Location = New-Object "System.Drawing.Point" (50, 50);
$helloButton.Add_Click({[System.Windows.Forms.MessageBox]::Show("Hello Hoge !")});
$sampleForm.Controls.Add($helloButton);

# コマンドレット実行
Run-Form $sampleForm;


以上のコマンドを実行すると、フォームが表示され、すぐにPowerShellが入力待機状態となる。試しに以下のようなコマンドを実行してみると、PowerShellからフォームを操作できることが確認できる。

# フォームを最前面に固定
$sampleForm.TopMost = $True;
# フォームのタイトルを設定
$sampleForm.Text = "Sample Form";
# フォームの不透明度を設定
$sampleForm.Opacity = 0.5;
# フォームの位置を設定
$sampleForm.Location = New-Object "System.Drawing.Point" (0, 0);


フォーム表示後のコントロールの追加は、以下のように、Invokeメソッドを使用して行う。
Invokeメソッドを使用しない場合、エラーとなってしまうので注意。
なお、関数をEventHandler型にキャストしているのは、関数 ( ScriptBlockオブジェクト ) はEventHandler型にのみしかキャストできないためである。

$exitButton = New-Object "System.Windows.Forms.Button";
$exitButton.Text = "Exit";
$exitButton.Location = New-Object "System.Drawing.Point" (100, 100);
$exitButton.Add_Click({$sampleForm.Close()});
$sampleForm.Invoke([EventHandler]{$sampleForm.Controls.Add($exitButton)})


フォームを閉じる時は、普通にフォームの閉じるボタンから閉じることも、PowerShellから以下のコマンドを実行して閉じることもできる。

# フォームの破棄
$sampleForm.Dispose();

タグ: .NET PowerShell