KEN's .NET

[第7回] Consoleアプリケーションでフィルタプログラム3 - ConsoleApplicationクラス

ホーム > KEN's .NET > [第7回] Consoleアプリケーションでフィルタプログラム3 - ConsoleApplicationクラス

前回は行番号付加プログラムの仕様、作成するクラスの構成などの説明で終わってしまいました。 今回からは、そのクラス群の解説をしたいと思います。それぞれのクラスは概要を説明し、ソースコードを提示しながら、 新しい技術要素について、その場その場で解説します。
※私はVS.NETやVB.NET Standardなどを持っておらず、現在、使用しているのは.NET Framework SDK(SP1)です。

1.はじめに

紹介する自作クラスの構成と概略について、おさらいしておきましょう。 このプログラムを構成する要素として、スイッチの解釈、スイッチ解釈時のエラー処理、行番号付加の3つの要素があります。 アプリ本体であるLineNumbererクラス、スイッチ解釈担当のCommandLineSwitchクラス、エラー処理担当のConsoleErrorクラス、 この行番号付加プログラムに固有ではなくCUIプログラムで共通に使う処理部分の雛型のConsoleApplicationクラスです。

今回は、ConsoleApplicationクラスの説明をします。

2.ConsoleApplicationクラス

2.1.概要

このクラスの役割は、一般的なCUIプログラムの雛型を提供することです。 このクラスが提供する機能は、以下の通りです。

ReadLinesメソッド標準入力からの入力データをすべてArrayListに蓄える。 ArrayListは配列のような感じで使用できるサイズが自動調整されるコレクションクラス。
WriteLinesメソッド蓄えておいたすべてのデータを標準出力に出力する。
Linesプロパティ入力データは行単位でこのプロパティから参照/変更できる。
AnalyzeArgumentメソッドコマンドライン引数を解釈する抽象メソッド。 CUIプログラムがコマンドライン引数を解釈するということは各アプリで共通しているが、実際の処理はまったく異なるので、 雛形としては、このメソッドを提供することを宣言する。このメソッドの中身(実装)はこのクラスを継承したクラスが行う。
ShowUsageメソッドこのコマンド(アプリ)の使用方法を標準出力に表示するメソッド。

2.2.ソースコードと解説

   1:Imports System
   2:Imports System.IO
   3:Imports System.Collections
   4:
   5:' コンソールアプリケーションの基本クラス
   6:Public MustInherit Class ConsoleApplication
[ 新キーワード : MustInherit ]
MustInheritキーワードは、このクラスが「Must + Inherit = 継承しなければならない」クラスであることを示し、 抽象クラスを定義するときに利用します。
   7:    Private mLines As ArrayList = New ArrayList()
[ クラス : ArrayList ]
ArrayListクラスはSystem.Collections 名前空間に所属するコレクションクラスです。 コレクションクラスは旧VBのCollection、Dictionaryオブジェクトなどのような機能を持ったクラスのことをいい、 Addメソッドでデータを追加し、Removeメソッドでデータを削除できるので、動的な配列のような感覚で扱えます。 ここでは、ArrayList型の変数mLinesを宣言し、「New ArrayList()」の部分でArrayListのインスタンスを生成しています。
   8:
   9:    ' ReadLinesメソッドで読み取った行データを返す読み取り専用プロパティ。
  10:    Public ReadOnly Property Lines() As ArrayList
  11:        Get
  12:            Return mLines
  13:        End Get
  14:    End Property
[ プロパティの定義方法 ]
.NETでのプロパティの定義の基本形は以下のようなイメージになります。
Public Property プロパティ名() As 
    Get
        Return 内部用変数
    End Get
    Set(ByVal value As 型)
        内部用変数 = value
    End Set
End Property
  1. オブジェクト.プロパティ = プロパティに設定する値 ( 例: Text1.Text = "テキスト" )
  2. プロパティから取得した値を設定する変数 = オブジェクト.プロパティ ( 例: stringValue = Text1.Text )
1.の場合の処理を定義するのが、Set 〜 End Setの部分で、2.の場合の処理を定義するのが、Get 〜 End Getの部分です。 プログラムの10〜14行のプロパティの定義では、読み取り専用のプロパティ(Get〜End Getの処理しか行わないプロパティ)にするために、 ReadOnlyキーワードを使用しています。このReadOnlyプロパティはPublicとPropertyの間に指定します。 また、Returnキーワードも新キーワードです。これは戻り値を戻すときのキーワードです。
  15:
  16:    ' 標準入力からデータを読み取り、コレクションに蓄える
  17:    Public Sub ReadLines()
  18:        Dim line As String
  19:
  20:        Do 
  21:            line = Console.ReadLine()
  22:            If Not line Is Nothing Then
  23:                mLines.Add(line)
  24:            Else
  25:                Exit Do
  26:            End If
  27:        Loop
  28:    End Sub
[ クラス : Console ]
ReadLinesメソッドは、20〜27行目のDo 〜 Loop処理で標準入力からの入力をすべてArrayListに登録しています。 標準入力から1行入力を受けるのには、System.ConsoleクラスのReadLineメソッドを利用します。 このメソッドは、1行入力して最後にEnterキーを押した時点で、1行分のデータを返します(改行はそのデータには含まれません)。 返された1行分のデータは、23行目でArrayListのAddメソッドでmLinesに追加します。 ループ内で標準入力を受け続けますが、入力が終了したら(キーボード操作ならCtrl+Z、ファイルならファイルの終端(EOF))、 ReadLineメソッドはNothingを返しますので、変数lineがNothingかどうかを調べることで、 入力終了を判定します。
  29:
  30:    ' コレクションに蓄えておいたデータをすべて標準出力に書き出す
  31:    Public Sub WriteLines() 
  32:        Dim line As String
  33:
  34:        For Each line in mLines
  35:            Console.WriteLine(line)
  36:        Next
  37:    End Sub
[ クラス : Console ][ 列挙 : For Each 〜 Next ]
WriteLinesメソッドは、34〜36行目のFor Each 〜 Next処理でmLinesに蓄えた入力データをすべて標準出力に出力します。 変数mLinesはArrayListクラスなので、For Each文により中身を順次取り出すことができます。 標準出力への書き出しは、ConsoleクラスのWriteLineメソッドを使用します。データ+改行コードが出力されます。
  38:
  39:    ' ToDo: コマンドライン引数を解釈する。
  40:    ' @param  コマンドライン引数
  41:    ' @return 解釈成功 True, 解釈失敗 False
  42:    MustOverride Public Function AnalyzeArgument(ByVal CmdArgs() As String) As Boolean
  43:    
  44:    ' コマンドの使用方法を標準出力に出力する
  45:    Public Sub ShowUsage()
  46:        ShowUsage(Console.Out)
  47:    End Sub
  48:
  49:    ' ToDo: コマンドの使用方法を指定の出力先に出力する。
  50:    ' @param 出力先
  51:    MustOverride Public Sub ShowUsage(ByVal out As TextWriter)
  52:End Class
[ 新キーワード : MustOverride ]
MustOverrideはVB.NETからの新キーワードで42行目と51行目で使用しています。 このメソッドが「Must+Override = オーバーライドしなければらない」な抽象メソッドであることを示します。 このメソッドには中身は書きません(End Function等も書かない)。このクラスを継承したクラスの方で、 メソッドをオーバーライドして中身を実装しなければなりません。 AnalyzeArgumentはコマンドライン引数を解釈するメソッドですが、コマンドライン引数の仕様は各コマンドごとに異なるため、 共通クラスでは実装できません。実際にアプリを作成するときに実装したいので、未定義のメソッドとしています。 ShowUsageも使用方法のメッセージ、表示の仕方は、各コマンド依存のためここでは未定義にしています。
[ 新キーワード : Overloads ]
Overloadsという新キーワードがあります。コード中でそんなキーワード出てこないじゃないか!!と思われるかもしれませんが、 省略しているだけだったりします。45行目と51行目をご覧下さい。両方ともShowUsageで同じ名前のメソッドです。しかし、引数の指定が異なります。 これをオーバーロードといいます。 同じ名前のメソッドで引数の型、数、順番のいずれかの異なるものを多重に定義することです。同クラス内でオーバーロードさせる場合は、特にOverloadsキーワードを指定する必要はありません。 しかし、基本クラスでメソッドAを定義し、それを継承したクラスでメソッドAの別バージョンをオーバーロードで定義する場合はOverloadsキーワードの指定が必須です。 ShowUsageメソッドを2つ用意しているのは、以下のような理由によります。
  • 基本的には標準出力に使用方法を出力する
  • ただし、場合によって、標準エラー出力に出力したい

3.まとめ

今回は、ConsoleApplicationクラスのメソッド、プロパティの概要を紹介し、ソースは順を追って目新しいところを説明しました。


ホーム > KEN's .NET > [第7回] Consoleアプリケーションでフィルタプログラム3 - ConsoleApplicationクラス

[e-mail] yone_ken00@hotmail.com