2009年2月13日金曜日

.NET 定数ファイルを作成する~その2~

今回はWeekDayクラス、WeekDayHasNoneクラス、WeekDayHasNotSunクラスに
インスタンス化せずにCDから名前を検索できるメソッドを追加します。

前回、作成したコードをまとめるとこんな感じです。
NameSpace Constant
Public Class ConstItem
Private _Cd As Integer
Private _Name As String
Private _AliasName As String

Private Sub New
End Sub 

Public Sub New(cd As Integer, name As String)
Me._Cd = cd
Me._Name = name
Me._AliasName = String.Empty
End Sub

Public Sub New(cd As Integer, name As String, aliasName As String)
Me._Cd = cd
Me._Name = name
Me._AliasName = aliasName
End Sub

Public ReadOnly Property Cd() As Integer
Get
Return Me._Cd
End Get
End Property

Public ReadOnly Property Name() As String
Get
Return Me._Name
End Get
End Property

Public ReadOnly Property AliasName() As String
Get
Return Me._AliasName
End Get
End Property

End Class
End NameSpace


NameSpace Constant
Public Class WeekDay
Public Shared ReadOnly SUN As New ConstItem(1, "日曜日","日")
Public Shared ReadOnly MON As New ConstItem(2, "月曜日","月")
Public Shared ReadOnly TUE As New ConstItem(3, "火曜日","火")
Public Shared ReadOnly WED As New ConstItem(4, "水曜日","水")
Public Shared ReadOnly THR As New ConstItem(5, "木曜日","木")
Public Shared ReadOnly FRI As New ConstItem(6, "金曜日","金")
Public Shared ReadOnly SAT As New ConstItem(7, "土曜日","土")

Public Shared Function CreateList As List(Of ConstItem)
Dim list As New List(Of ConstItem)
list.Add(SUN)
list.Add(MON)
list.Add(TUE)
list.Add(WED)
list.Add(THR)
list.Add(FRI)
list.Add(SAT)
Return list
End Function
End Class

Public Class WeekDayHasNone
Inherits WeekDay

Public Shared ReadOnly NONE As New ConstItem(0, "なし")

Public Shared Shadows Function CreateList As List(Of ConstItem)
Dim list As List(Of ConstItem)
list = WeekDay.CreateList
list.InsertAt(0,NONE)
Return list
End Function
End Class

Public Class WeekDayHasNotSun
Inherits WeekDay

Private Shared Shadows ReadOnly SUN As New ConstItem(1, "日曜日","日")

Public Shared Shadows Function CreateList As List(Of ConstItem)
Dim list As List(Of ConstItem)
list = WeekDay.CreateList
list.RemoveAt(WeekDay.SUN)
Return list
End Function
End Class
End NameSpace



簡単に思いついたのは各クラスに下記のようなコードを追加していくことでした。
Public Shared Function Find(ByVal cd As Integer) As ConstItem
Dim item As ConstItem = Nothing
Dim list As List(Of ConstItem) = 各クラス名.CreateList
       For idx As Integer = 0 To list.Count - 1
             If list.Item(idx).Cd = cd Then
item = list.Item(idx)
Continue For
End If
Next
Return item
End Function

・・・これじゃぁダメだよね(;´∀`)


次に思いついたのはList<Of T>のFindメソッドで探すことです。
Findメソッドの使い方は以下のようなコードになります。
これが結構面倒なんですよね。
Public Class Test

Private _SearchCd As Integer

Public Sub Test()
Dim list As New List(Of KeyValuePair(Of Integer, String))
list.Add(New KeyValuePair(Of Integer, String)(1, "日曜日"))
list.Add(New KeyValuePair(Of Integer, String)(2, "月曜日"))
list.Add(New KeyValuePair(Of Integer, String)(3, "火曜日"))

'CD=2を検索
Me._SearchCd = 2
Dim findItem As KeyValuePair(Of Integer, String) = list.Find(AddressOf IsMatch)
If IsNothing(findItem) Then
Console.WriteLine("該当データなし")
Else
Console.WriteLine("Key:{0},Value:{1},", findItem.Key, findItem.Value)
End If

End Sub

Private Function IsMatch(ByVal item As KeyValuePair(Of Integer, String)) As Boolean
Return item.Key = Me._SearchCd
End Function
End Class




そこでList(Of T)を継承したConstListクラスを作成し、Find(Cd)メソッドを追加します。
ついでに名前から検索するFind(Name)も作っておきます。
Namespace Constant
  ''' <summary>
''' 定数アイテムのリストを管理するクラスです。
''' </summary>
''' <remarks></remarks>
Public Class ConstList
Inherits List(Of ConstItem)

''' <summary>
''' CDに該当する最初のConstItemを取得します。
''' </summary>
''' <param name="cd"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Overloads Function Find(ByVal cd As Integer) As ConstItem
Dim filter As New ConstItemFilter(Of Integer)
filter.FilterValue = cd
Return Me.Find(AddressOf filter.IsMatchCd)
End Function

''' <summary>
''' Nameに該当する最初のConstItemを取得します。
''' </summary>
''' <param name="name"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Overloads Function Find(ByVal name As String) As ConstItem
Dim filter As New ConstItemFilter(Of String)
filter.FilterValue = name
Return Me.Find(AddressOf filter.IsMatchName)
End Function

End Class

End Namespace


Findメソッドで実際に検索するFilterクラスを作成します。
Namespace Constant
  ''' <summary>
  ''' 定数リストより定数アイテムを検索するためのFilterクラスです。
  ''' </summary>
''' <remarks></remarks>
Public Class ConstItemFilter(Of TValue)

    ''' <summary>検索する値です</summary>
Private _FilterValue As TValue

    ''' <summary>デフォルトコンストラクタ</summary>
Public Sub New()
End Sub

    ''' <summary>コンストラクタ</summary>
    ''' <param name="filterValue">検索する値</param>
Public Sub New(ByVal filterValue As TValue)
Me.New()
Me._FilterValue = filterValue
End Sub

    ''' <summary>検索する値を取得および設定します。</summary>
Public Property FilterValue() As TValue
Get
Return _FilterValue
End Get
Set(ByVal value As TValue)
_FilterValue = value
End Set
End Property
    
    ''' <summary>引数に指定した定数アイテムのCDと検索値が一致するかを取得します。</summary>
    ''' <param name="item">定数アイテム</param>
    ''' <returns>一致する場合はTrue。それ以外はFalse。</returns>
Public Function IsMatchCd(ByVal item As ConstItem) As Boolean
If (Me._FilterValue Is Nothing) Then Return False
Return (Me._FilterValue.Equals(item.Cd))
End Function

    ''' <summary>引数に指定した定数アイテムのNameと検索値が一致するかを取得します。</summary>
    ''' <returns>一致する場合はTrue。それ以外はFalse。</returns>
Public Function IsMatchName(ByVal item As ConstItem) As Boolean
If (Me._FilterValue Is Nothing) Then Return False
Return (Me._FilterValue.Equals(item.Name))
End Function
End Class
End Namespace


ConstItemクラスの修正はありません。
Namespace Constant
  ''' <summary>
  ''' 定数アイテムクラスです。
  ''' </summary>
''' <remarks></remarks>   
Public Class ConstItem
    ''' <summary>コードです</summary>
Private _Cd As Integer
    ''' <summary>名前です</summary>
Private _Name As String
    ''' <summary>別名です</summary>
Private _AliasName As String
    
    ''' <summary>デフォルトコンストラクタ</summary>
Private Sub New()
End Sub
    
    ''' <summary>コンストラクタ</summary>
    ''' <param name="cd">コード</param>
    ''' <param name="name">名前</param>
Public Sub New(ByVal cd As Integer, ByVal name As String)
Me._Cd = cd
Me._Name = name
Me._AliasName = String.Empty
End Sub

    ''' <summary>コンストラクタ</summary>
    ''' <param name="cd">コード</param>
    ''' <param name="name">名前</param>
    ''' <param name="aliasName">別名</param>
Public Sub New(ByVal cd As Integer, ByVal name As String, ByVal aliasName As String)
Me._Cd = cd
Me._Name = name
Me._AliasName = aliasName
End Sub
  
    ''' <summary>コードを取得します。</summary>
Public ReadOnly Property Cd() As Integer
Get
Return Me._Cd
End Get
End Property

    ''' <summary>名前を取得します。</summary>
Public ReadOnly Property Name() As String
Get
Return Me._Name
End Get
End Property

    ''' <summary>別名を取得します。</summary>
Public ReadOnly Property AliasName() As String
Get
Return Me._AliasName
End Get
End Property
End Class

End Namespace

定数ファイルのCreateListメソッドを修正し、ConstListクラスを返すようにします。
Namespace Constant
  ''' <summary>
  ''' 曜日リストです。
  ''' </summary>
''' <remarks></remarks>  
Public Class WeekDay
Public Shared ReadOnly SUN As New ConstItem(1, "日曜日", "日")
Public Shared ReadOnly MON As New ConstItem(2, "月曜日", "月")
Public Shared ReadOnly TUE As New ConstItem(3, "火曜日", "火")
Public Shared ReadOnly WED As New ConstItem(4, "水曜日", "水")
Public Shared ReadOnly THR As New ConstItem(5, "木曜日", "木")
Public Shared ReadOnly FRI As New ConstItem(6, "金曜日", "金")
Public Shared ReadOnly SAT As New ConstItem(7, "土曜日", "土")

Public Shared Function CreateList() As ConstList
Dim list As New ConstList
list.Add(SUN)
list.Add(MON)
list.Add(TUE)
list.Add(WED)
list.Add(THR)
list.Add(FRI)
list.Add(SAT)
Return list
End Function

End Class

  ''' <summary>
  ''' なしを保有する曜日リストです。
  ''' </summary>
''' <remarks></remarks>   
Public Class WeekDayHasNone
Inherits WeekDay

Public Shared ReadOnly NONE As New ConstItem(0, "なし")

Public Shared Shadows Function CreateList() As ConstList
Dim list As ConstList
list = WeekDay.CreateList
list.Insert(0, NONE)
Return list
End Function

End Class

  ''' <summary>
  ''' 日曜日を保有しない曜日リストです。
  ''' </summary>
''' <remarks></remarks>     
Public Class WeekDayHasNotSun
Inherits WeekDay

Private Shared Shadows ReadOnly SUN As New ConstItem(1, "日曜日", "日")

Public Shared Shadows Function CreateList() As ConstList
Dim list As ConstList
list = WeekDay.CreateList
list.Remove(WeekDay.SUN)
Return list
End Function


End Class
End Namespace


使い方
'名前を取得します。
Console.WriteLine(Constant.WeekDay.SUN.Name)
'別名を取得します。
Console.WriteLine(Constant.WeekDay.SUN.AliasName)

'コンボボックスに設定します。
ComboBox1.ValueMember = "Cd"
ComboBox1.DisplayMember = "Name"
'別名の場合
'ComboBox1.DisplayMember = "AliasName"
ComboBox1.DataSource = Constant.WeekDay.CreateList

'CD=1に該当する定数アイテムを取得します。
Dim findCd As Integer = 1
Dim findItem As ConstItem = WeekDay.CreateList.Find(findCd)
If IsNothing(findItem) Then
Console.WriteLine("Cd={0}に該当するアイテムはありません。",findCd)
Else
Console.WriteLine("Cd:{0},Name:{1},Name:{2}",findItem.Cd, findItem.Name, findItem.AliasName")
End If

'Name="木曜日"に該当する定数アイテムを取得します。
Dim findName As String = "木曜日"
Dim findItem As ConstItem = WeekDay.CreateList.Find(findName)
If IsNothing(findItem) Then
Console.WriteLine("Name={0}に該当するアイテムはありません。",findName)
Else
Console.WriteLine("Cd:{0},Name:{1},Name:{2}",findItem.Cd, findItem.Name, findItem.AliasName")
End If




難点はCdから定数アイテムを検索する際にCreateList経由でしかできない事です。
一応これで要件はすべて満たしたのでOKとします。

0 件のコメント: