merさんのブログ

[Effective C#] 項目28 変換演算子は使用しないこと

また日が空いてしまいました。本日の Effective C# は「変換演算子は使用しないこと」です。

ある機能を使うな! というのも何なんですが、作ったはいいけど、うまく機能しないとか多いんですよね。たとえば、ApplicationException クラス

変換演算子もこれほどじゃないんですけど、意図しない動作をすることがあるので、使いづらいです。

変換演算子は 以下のように利用します。

[Effective C#] 項目27 ICloneable を使用しないこと

本日の Effective C# は「項目27 ICloneable を使用しないこと」です。

オブジェクトクローンって難しいんですよね。いや、作るのはそんなに難しくないんですが、浅いコピーにするか、深いコピーにするかで非常に悩みます。

コピーを作成するには、ICloneable インターフェイスを実装します。

値型に関しては、そもそも代入でコピーが作成されるため、ICloneable を実装する必要はないそうです。

参照型の場合は…。一般的には深いコピーを行うんだと思います。

IClonebale インターフェイスを実装するのであれば、すべての派生クラスでもこのインターフェイスを実装しなければいけないのです。

なので、ドキュメントにきちんと記述して、これらを行うよう促さないといけないですね。

[Effective C#] 項目26 IComparable と IComparerer を実装して順序関係をサポートする

これで半分過ぎました。本日の Effective C# は「項目26 IComparable と IComparerer を実装して順序関係をサポートする」です。

IComparable インターフェイスはオブジェクトを比較可能にするものです。比較というのは大小関係を決めるもので、既定のソートに利用されます。それに対し、IComparer インターフェイスはオブジェクトの比較を行います。

書籍のほうでは、IComparable インターフェイスの実装は明示的に行い、オーバーロードで引数の型を明示的に指定した CompareTo メソッドを定義したりしていますが…。(構造体のボクシング・案ボクシング対策のためだそうです)

[Effective C#] 項目25 型はできるだけシリアル化可能とすること

最近ペースが落ちてますので、今日からまた頑張ります。本日の Effective C# は「項目25 型はできるだけシリアル化可能とすること」です。

これはちょっと疑問に思いました。シリアル化の必要が出てからシリアル化可能にすればいいんじゃないかと。

独自に作成した型がシリアル化を適切にサポートしていない場合、その型をメンバとして使用したり、親クラスとして実装したい開発者に余計な手間をかけさせることになるでしょう。型がシリアル化をサポートしないのであれば、型を使用する側でなんとかしてシリアル化の対象とできるよう独自の実装を行うことになります。しかし型を使用する側では型の内部に定義された private メンバへアクセスすることはできないため、シリアル化を適切にサポートできるはずもありません。型の開発者自身がシリアル化をサポートしない限り、外部からシリアル化をサポートできるようにすることはほぼ不可能です。

つまりは、特に Framework みたいなものを作る場合、それらがシリアル化不可能な場合、それを使う人がシリアル化したいと思っても、難しいので、とりあえずやっとけみたいな感じですね。

ReSharper の Code Generation で Equals()/GetHashCode() メソッドの実装を行う

ReSharperCode Generation が便利すぎです。

ソースコードの型の上で Alt + INS を押してください。ポップアップメニューが出てきます。

メンバを指定して、コンストラクタを生成したりは序の口です。

"Generate Formatting Members" を選ぶと、選択したメンバを利用して、ToString() メソッドを実装してくれます。メンバの数が多い場合に、ToString() メソッドを実装することは大変な労力なので、これは助かります。

一番驚いたのが、"Generate Equality Members" です。これは、指定したメンバを利用して、Eqals()/operator==()/operator!=() を実装してくれます。さらには、GetHashCode() まで実装してくれます。

[Effective C#] 項目24 命令型プログラミングよりも宣言型プログラミングを選択する

本日の Effective C# は「項目24 命令型プログラミングよりも宣言型プログラミングを選択する」です。

この項目は長いので書籍を読んでください。(笑)

要約すると、属性を用いた宣言型プログラミングをやろうねってことです。たぶん。

宣言型プログラミングとは、命令を記述するのではなく、ふるまいを宣言することによってプログラムを作成する方法です。

カスタム属性を作ることで、クラスやメンバに情報を入れ込むことができます。これにより、さまざまなことが可能になります。

[Effective C#] 項目23 クラス内のオブジェクトの参照を返さないようにすること

本日の Effective C# は「項目23 クラス内のオブジェクトの参照を返さないようにすること」です。

これ大事なんですけどね。守りたいんですが、ついつい面倒で…。

[Effective C#] 項目22 イベントにより発信インターフェイスを定義する

本日の Effective C# は「項目22 イベントにより発信インターフェイスを定義する」です。

まあ、なんらかの通知をする場合はイベントを使用した方がいいですよー。というお話なんですが、ひとつチンプンカンプンなところがありました。

(ほとんどの Windows コントロールのように) 非常に多くのイベントを必要とするクラスも少なくありません。その場合、ひとつのイベントに一つのイベントフィールドを定義することはほぼ不可能です。たとえ多くのイベントを定義したとしても、実際には定義されたイベントのうちの一部だけがアプリケーション内で使用されていることでしょう。このような状況に遭遇した場合、実行時に必要となるイベントオブジェクトだけを定義するよう設計を見直すべきです。

ここの意味がさっぱりわかりません。

Windows コントロールはイベントごとにイベントフィールドを用意していますし、それじゃあかんと言われても…。なぜ見直すべきかの理由も書いていないですし…。

Drupal でノードのサブミットボタン押下時にタームがクリアされる

tag: 

Drupal にはタクソノミモジュールというのがあって、タグみたいなものを提供できる。

これはいいんだけど、

$form['add_material'] = array(
  '#type' => 'submit',
  '#value' => t('Submit'),
  '#weight' => -6,
  '#submit' => array('_customnode_submit'),
);

こんな感じにカスタムノードにボタンをつけてですね。

function _customnode_submit($form, &$form_state) {
  $node = node_form_submit_build_node($form, $form_state);
}

こんな感じで。

そして、タームを適当に選択して Submit ボタンを押すと、あら不思議! 選択済みのタームがクリアされるという悲しい自体が…。

あまりにも悲しいのでソースコードを本気で追ってみました。

[Effective C#] 項目21 デリゲートを使用してコールバックを実現する

本日の Effective C# は「項目21 デリゲートを使用してコールバックを実現する」です。

コールバックは激しく便利です。C# はデリゲートというのがあるので、これを利用してコールバックが書けます。Java だとこれがないのでインターフェイスを利用する必要があります。

特定のクラス間でデータをやり取りする必要があるけども、互いのインターフェイスを使用するほどには密に連携させたくない場合、デリゲートは最善の選択肢だといえます。

そうなんですよね。ちょろっとしたことなら、インターフェイスよりデリゲートの方が便利なんですよね。

マルチキャストデリゲートは複数のメソッドが登録されたデリゲートで、1 回の呼び出しで登録されたメソッドを呼び出すことができます。ただし注意すべき点が 2 つあります。一つは例外に対して安全ではないこと、もうひとつはマルチキャストデリゲートの返り値は最後に実行されたメソッドの返り値になるということです。

例外の件はともかくとして、返り値が一つしか、しかも最後のメソッドのもののみってのは大問題な気がします。

ページ

RSS - merさんのブログ を購読