2017.03.06
yna 開発

久しぶりのC#

 普段はPHPを中心にプログラムして、ちょっとPerlを使ったり。Rubyをいじったりしているのですが、今回、数年ぶりにC#を書いています。

 C#は、Microsoftが作成したC++やJavaに影響を受けたオブジェクト指向言語で、Windowsで、.netフレームワークという共通化されたライブラリをベースに動きます。iOS(MacやiPhone)やAndroidなどは、フレームワーク部分が異なるため、そのままでは動きませんが、Xamarinという互換性の高いフレームワークがあるので、これを利用するとiOSやAndroidもクロス開発ができるらしいです。
 C#は結構Java並みに型のチェックの煩い言語です。とはいえ組み込み型の値とクラスのオブジェクトの動作が異なるなど、純粋オブジェクト指向言語とはいえないようです。

 今回作るのはWindowsのフォームタイプのアプリケーションです。フォームのタイプのアプリケーションというのは、画面に部品を貼り付けて、それに付随したコードを書いて、動作を検証して、また、デバッグして、コードしては難しくないのだけど、ひたすら面倒。
 現状で動いているコードを参考に移植を進めていくのですが、Webでこういう動的な入力部分を作ると、AJAXを駆使して作らざるを得なくなるので、とても大変だけど、C#はひたすら面倒なだけ。

 一方PHPだと連想記憶配列があってこれを構造体のように使ったりできるのだけど、C#では、ひたすらクラスを作ることになります。Formは10個くらいなのに、クラスファイルは20。中には、ベースのクラスとそのリストの二組を書いているものもあって、30近くのクラスが。ちょっとクラスの作りすぎ?
(しかし言語設計の拙さが原因じゃないだろうか?)

 今回作ったクラスで、CSelectItemというクラスがある。プルダウンなどの選択肢を入れておくクラス。

public class CSelectItem
{
    public string      Code;
    public string      Name;
    //  
    public CSelectItem(string code, string name)
    {
        this.Code = code;
        this.Name = name;
    }
}

 実際はこれはリストがあって意味のあるクラスなので、リストのクラスも作成。
 Codeで検索したり、Nameで検索したりするので、こんな関数を追加
  ・indexOfCode
  ・indexOfName
 取りあえずは、普通の関数で書いたのだけど、ジェネリック型とか、ラムダ式を使えば汎用的になりそう。

public class ListSelectItem : List
{
  ・・・
  //==============================================================
  // コード検索
  public int   indexOfCode(string code, int start = 0, int count = -1)
  {
    int range = ((count < 0)|| (start + count >= this.Count))
        ? this.Count : (start + count);
    for( int i = start ; i < range ; i++){       if( this[i].Code == code ) return i;     }     return -1;   }   //==============================================================   // 名称検索   public int   indexOfName(string name, int start = 0, int count = -1)   {     int range = ((count < 0)|| (start + count >= this.Count))
        ? this.Count : (start + count);
    for( int i = start ; i < range ; i++){       if( this[i].Name == name ) return i;     }     return -1;   }   //==============================================================   ・・・ }

 そっくりな関数を二個書くのはバカらしいので、ラムダ関数を使ってまとめます。ついでにListクラスを継承してListExクラスを作成こちらに移動。

public class ListSelectItem : List
{
  ・・・
  //==============================================================
  // コード検索
  public int   indexOfCode(string code, int start = 0, int count = -1)
  {
    int range = ((count < 0)|| (start + count >= this.Count))
        ? this.Count : (start + count);
    for( int i = start ; i < range ; i++){       if( this[i].Code == code ) return i;     }     return -1;   }   //==============================================================   // 名称検索   public int   indexOfName(string name, int start = 0, int count = -1)   {     int range = ((count < 0)|| (start + count >= this.Count))
        ? this.Count : (start + count);
    for( int i = start ; i < range ; i++){       if( this[i].Name == name ) return i;     }     return -1;   }   //==============================================================   ・・・ }

 rubyだと、以下の式で一発なんだけど、
idx = ary.index {|i| i.code == find }

 まあ、これくらいなら、許容範囲かな?
idx = list.indexOf( (CSelectItem item) => { return ( item.Name == name ); })

yna

一覧に戻る