R.Tanaka.Ichiro's Blog

主にC# な話題です

目次

Blog 利用状況

ニュース

Link

Author

Contact

History

Accessories

書庫

2008年10月6日

引数の順番の統一について

public ArgumentException(string message, string paramName);
public ArgumentOutOfRangeException(string paramName, string message);

message と paramName の順番が逆じゃねーか、ややこしいぜ。

まー

インテリセンス

があるからいいけどw

posted @ 10:38 | Feedback (5)

2008年10月3日

なるべく流れ制御を回避する

題名のようなテーマで以前エントリーをあげました。
確か、以下だったと思います。

http://blogs.wankuma.com/rti/archive/2008/09/29/157748.aspx
風邪をこじらせたようだ

熱に浮かされながら、つらつらと書いただけあって、言いたいことを深く考えもせずに語っております。

で、この話題をどうやって終わらせようか?、などと書いたことを後悔しつつも、このままというのも気持が悪いので何とかまとめていこうと思います。

以下のコードは、処理の流れを利用することで目的となる回答を得ています。


private bool Search(string[] array, string target) {
  foreach(var x in array) {
    if (x == target) return true;
  }
  return false;
}


これは LINQ を使うことで以下のように、自ら

流れ制御文を記述することなく

同じ結果を得ることができます。


private bool Search2(string[] array, string target) {
  return array.Where(x => x == target).Select(x => true).FirstOrDefault();
}


また、LINQ を使わなくても、流れ制御部分と本来の目的の部分を分離することによって、自らが流れ制御文を書く機会を減らすこともできます。
上記の処理は、以下の 2 つの処理に分離できます。


(1) 全要素分だけ反復したら false を返し、中断指示を受けたら true を返す処理

private bool LoopUntil<T>(IEnumerable<T> source, Func<T, bool> until) {
  foreach(var x in source) {
    if (until(x)) return true;
  }
  return false;
}


(2) 文字列配列中の要素に、特定の文字列が存在するかどうかを判定する処理

private bool Search3(string[] array, string target) {
  return this.LoopUntil<string>(array, x => x == target);
}


このように流れ制御文をカプセル化するのも、僕としてはアリかなー、と思っています。

posted @ 13:36 | Feedback (6)

2008年10月2日

2008年09月度ページビュー

日付 ブログ数
2008/09/01 1,796
2008/09/02 2,442
2008/09/03 2,216
2008/09/04 2,609
2008/09/05 1,651
2008/09/06 914
2008/09/07 707
2008/09/08 1,962
2008/09/09 2,703
2008/09/10 2,105
2008/09/11 2,038
2008/09/12 2,170
2008/09/13 1,290
2008/09/14 678
2008/09/15 1,055
2008/09/16 2,398
2008/09/17 2,537
2008/09/18 2,570
2008/09/19 2,224
2008/09/20 1,043
2008/09/21 699
2008/09/22 1,926
2008/09/23 886
2008/09/24 2,051
2008/09/25 1,618
2008/09/26 2,262
2008/09/27 820
2008/09/28 638
2008/09/29 1,794
2008/09/30 2,088
合計 51,890

いつもありがとうございます~

posted @ 13:48 | Feedback (0)

2008年9月30日

Vista の My Documents フォルダは頑固だった

メインマシンが壊れたので修理に出すことになった。

メインマシンの OS は Vista Bussiness だった。

修理に出している間、サブマシンを使うことになった。

サブマシンの OS は XP Pro だった。

サブマシンとメインマシンは、どちらも全く同じドメインユーザーアカウントだった。

メインマシンからハードディスクを抜いて、サブマシンに認識させた。

サブマシンで、メインマシンのハードディスクにアクセスしてみたところ問題なさそうだった。

メインマシンは修理に出した

暫くして、メインマシンのハードディスクドライブの :\Users\ore.domain\My Documents\ にアクセスして見た。

「アクセスが拒否されました」というエラーメッセージが表示された。

x:\Users\ore.domain\My Documents\  のアクセス権の変更をしようと思った。

アクセス権タブが、このフォルダだけ表示されず途方に暮れた。

ブログでネタにしたら、誰か助けてくれるかな?・・・と思った ←今ココ

posted @ 15:44 | Feedback (5)

2008年9月29日

風邪をこじらせたようだ

http://blogs.wankuma.com/rti/archive/2008/09/26/157515.aspx
風邪をひいたようだ

の続きです。

いや、別に前回のエントリーと絡めたところで何か得られるものがあるという訳ではありません。

今日は、

風邪をこじらせてしまって

高熱が出ているので、会社を休んで自宅で寝ています。

そんな訳で、いつものように仕事しながら何かネタを書くこともできませんし、頭もフラフラするので、徒然なるままなエントリーをあげてみます。

 

で、まず最初に、頭に浮かんだのは、最近良く思うことについてです。

次に頭に浮かんだのが、流れ制御文を必要以上に記述しない方が良いのではないかと言うことを、最近良く思う・・・ということでした。

何故なら、単純に上から順次処理を実行させる場合と比較して、流れ制御部分にバグが潜む可能性の方が高いと思うからです。

例えば、以下のような書き方です。


if (this.IsHoge) {
  return true;
}
return false;


このコードは、戻り値を変化させる目的を実現するために、if 分によってメソッドの処理の流れを制御しています。
つまり、条件が真なら、その後のコードは実行されないことを利用して書かれているため、その後のコードに変更を加える場合には、若干の注意が必要になります。

このコードは、比較演算結果を返すだけで同様の結果が得られます。


return this.IsHoge;


これによって、最初のコードに比べてバグが入る余地が少なくなると考えられます。

戻り値が bool 型ではない場合も、条件演算子を使うことで、流れ制御文を書くことを回避できます。


return this.IsHoge ? 1 : 0;


この記述も、最初のコードよりもバグが入る余地が少ないと考えられます。

また、反復処理による流れ制御も、なるべく排除するようにしています。
例えば、以下のコードは反復処理をすることで、目的となる結果を得ています。
しかし、反復処理自身が流れ制御ですし、その結果を戻す処理も処理の流れを制御するためのコードになっています。


private bool Search(string[] array, string target) {
  foreach(var x in array) {
    if (x == target) return true;
  }
  return false;
}


上記は LINQ を使うことで流れ制御文を書かずに済みます。

・・・と、ここまで書いて、ちょっと辛くなってきました。

続きは、また次の機会に書こうかと・・・orz

 

posted @ 19:14 | Feedback (4)

2008年9月26日

風邪をひいたようだ

風邪をひいたようだ。調子が悪い。

どのくらい調子が悪いかと言うと

つい先ほど書いたコードの一部をご覧いただければ一目瞭然だ。

public string ToBarcode(byval code, byval price

VB歴長かったからな~www

耐えてバグ含有率の高いコードを生産するか、大人しく家に帰って寝るか・・・

posted @ 9:43 | Feedback (7)

2008年9月25日

アセンブリの分け方が悩ましい

アセンブリの分け方

の規則を徹底しようと思っています。

そこで、皆さんは実際どうしているのかを聞いてみたくなりました。

例えば、マスターと実データの二つのデータ編集ツールがあって、これらのツールは一つのアプリケーションとして関連性が高いとします。

このような時、最初は以下のように分けていました。

R.Main
R.Widows.Forms
R.Model
R.Data

各アセンブリが何をするのかは名前の通りなので言及しませんが、このような分類だと参照するアセンブリの依存関係も綺麗に縦割りになります。
しかし、最近は、マスターと実データという機能別にアセンブリを分離する方が、分かりやすいし処理効率が良いのではないかということで、これも実践しています。

R.Main
R.RealData
R.Master

このように分類しておくと、アプリケーションが肥大化するほどに、利点が大きくなります。
例えば、印刷と環境設定画面の 2 つの機能を追加してみます。

R.Main
R.RealData
R.Master
R.Print
R.Config

上記のように機能が追加された時、アセンブリ単位で分類できていれば管理も楽ですし、印刷や環境設定など利用する可能性の低い機能が分離されていることで処理効率も高くなるであろうことが予想されるからです。
そこで、最近は以下のようにアセンブリを細かくしています。

R.Main
R.Widows.Forms
R.Model
R.Data
R.RealData
R.Master

上の 3 つは、R.RealData, R.Master で共通して利用するアセンブリで依存関係は以下のようになります。

R.Main
 R.RealData
  R.Widows.Forms
  R.Model
  R.Data
 R.Master
  R.Widows.Forms
  R.Model
  R.Data

小さいアプリケーションは、ひとつのアセンブリにまとめてしまうのですが、結局は後で分離することが多いので今後は最初から分けてしまうかと思っています。

posted @ 13:17 | Feedback (3)

2008年9月24日

System.ServiceModel が必要なのね

軽くハマったのでメモ。

新しく作ったプロジェクトを WCF Client とすべく、サービス参照の追加をしても、指定した名前空間以下が空っぽでクラスを生成してくれないという現象が起きた。
どうやら、メタデータの取得に失敗しているらしい。
で、何が原因かと調べてみたら、どうやら参照するアセンブリに

System.ServiceModel

が含まれていないことが原因らしい。

これって、サービス参照追加を最初に実行することで自動的に追加してくれる筈だと思ったんだけどなぁ・・・

まぁ、手動で追加したら無事 WCF サービス参照が追加できたので一件落着です。

posted @ 12:32 | Feedback (0)

2008年9月22日

20回繰り返せるだけで良かった

深い意味は無い。

ただ 20 回繰り返せれば

それだけで良かったんだ。


class Program
{
  static void Main(string[] args) {
    20.Loop(() => Console.WriteLine("R"));
    Console.ReadKey();
  }
}

static class Ex {
  public static void Loop<T>(this T value, Action action) where T : struct {
    foreach(var i in Enumerable.Range(0, int.Parse(value.ToString()))) action();
  }
}


なんか調子悪いな~

posted @ 14:05 | Feedback (3)

2008年9月19日

とても似ているメソッドの共通化

今リアルで書いてある 4 つのメソッドは、とても似ている訳だ。
基本的に、先頭と末尾に同じ処理がダラダラとあって、その真ん中に各メソッド特有の処理が来る。

例えば、こんな感じ。(あんまり良いサンプルじゃないけど)


public Test1() {
  Console.WriteLine(this.A(true));
  Console.WriteLine(this.B(1, true));
  Console.WriteLine(this.C("R", 2, false));
  Console.ReadKey();
}

public int A(bool b) {
  Console.WriteLine("----------------------------------");
  Console.WriteLine(DateTime.Now.Ticks);
  Console.WriteLine("----------------------------------");
  Console.WriteLine("A : {0}", b);
  Console.WriteLine("--");
  return 1;
}

public string B(int i, bool b)  {
  Console.WriteLine("----------------------------------");
  Console.WriteLine(DateTime.Now.Ticks);
  Console.WriteLine("----------------------------------");
  Console.WriteLine("B:{0}, {1}", i, b);
  Console.WriteLine("--");
  return "R";

}

public bool C(string s, int i, bool b)  {
  Console.WriteLine("----------------------------------");
  Console.WriteLine(DateTime.Now.Ticks);
  Console.WriteLine("----------------------------------");
  Console.WriteLine("C:{0}, {1}, {2}", s, i, b);
  Console.WriteLine("--");
  return true;
}


引数の型や数、戻り値の型が同じならデリゲートで共通化できるのになぁ・・・と悩んでいたのですが、よくよく考えてみればデリゲートって外側の変数をそのまま使えちゃうんでしたっけ。
なんだ、簡単じゃん・・・orz

以下にように、

とても似ているメソッドの共通化

してみた。


public Test2() {
  Console.WriteLine(this.A(true));
  Console.WriteLine(this.B(1, true));
  Console.WriteLine(this.C("R", 2, false));
  Console.ReadKey();
}

public int A(bool b) {
  int r = 0;
  D(() => { Console.WriteLine("A : {0}", b); r = 1; });
  return r;
}

public string B(int i, bool b)  {
  string r = string.Empty;
  D(() => { Console.WriteLine("B:{0}, {1}", i, b); r = "R"; });
  return r;
}

public bool C(string s, int i, bool b)  {
  bool r = false;
  D(() => { Console.WriteLine("C:{0}, {1}, {2}", s, i, b); r = true; });
  return r;
}


public void D(Action a)  {
  Console.WriteLine("----------------------------------");
  Console.WriteLine(DateTime.Now.Ticks);
  Console.WriteLine("----------------------------------");
  a();
  Console.WriteLine("--");
}


なんか、気に入らないのでジェネリクスを使ってみた。


public Test3() {
  Console.WriteLine(this.A(true));
  Console.WriteLine(this.B(1, true));
  Console.WriteLine(this.C("R", 2, false));
  Console.ReadKey();
}

public int A(bool b) {
  return D(() => { Console.WriteLine("A : {0}", b); return 1; });
}

public string B(int i, bool b)  {
  return D(() => { Console.WriteLine("B:{0}, {1}", i, b); return "R"; });
}

public bool C(string s, int i, bool b)  {
  return D(() => { Console.WriteLine("C:{0}, {1}, {2}", s, i, b); return true; });
}

public T D<T>(Func<T> a)  {
  Console.WriteLine("----------------------------------");
  Console.WriteLine(DateTime.Now.Ticks);
  Console.WriteLine("----------------------------------");
  var r = a();
  Console.WriteLine("--");
  return r;
}


うーん、こんな感じで本番のコードも共通化できるかな。

posted @ 14:30 | Feedback (4)