前回に引き続き定数定義クラスについてです。
今回はT.Hiraseさんから
パクッた教えていただいたカスタム属性を使って名前付定数を定義してみました。
T.hiraseさんの記事:[C#] 名前付き定数・・・?ありがとうございます(人-)謝謝
前回に比べ、
定数を定義する際はConstantクラスに列挙体を追加するだけなので楽になりました。
しかし定数を使用する際が直感的に解りにくくなってしまいました。
DayOfWeek.CreateListで定数リストデータが作成できたり DayOfWeek.GetName(DayOfWeekの列挙子)で定数の名前を取れるようにしたいですね。
定数を定義する際は列挙体を使用してカスタム属性で定数名を定義します。
Public Class Constant
Public Enum DayOfWeek As Integer
<("日曜日"), AliasName("日")> _
Sun = 0
<("月曜日"), AliasName("月")> _
Mon = 1
<("火曜日"), AliasName("火")> _
Tue = 2
<("水曜日"), AliasName("水")> _
Wed = 3
<("木曜日"), AliasName("木")> _
Thu = 4
<("金曜日"), AliasName("金")> _
Fri = 5
<("土曜日"), AliasName("土")> _
Sat = 6
End Enum
Public Shared Function CreateList(ByVal enumType As Type) As List(Of ListItem)
Dim items As New List(Of ListItem)
For Each value As Object In [Enum].GetValues(enumType)
Dim name As String = NameAttribute.GetName(CType(value, [Enum]))
items.Add(New ListItem(value, name))
Next
Return items
End Function
Public Shared Function CreateAliasList(ByVal enumType As Type) As List(Of ListItem)
Dim items As New List(Of ListItem)
For Each value As Object In [Enum].GetValues(enumType)
Dim aliasName As String = AliasNameAttribute.GetAliasName(CType(value, [Enum]))
items.Add(New ListItem(value, aliasName))
Next
Return items
End Function
Public Shared Function GetName(ByVal enumType As Type, ByVal findValue As Object) As String
Return NameAttribute.GetName(CType(findValue, [Enum]))
End Function
Public Shared Function GetAliasName(ByVal enumType As Type, ByVal findValue As Object) As String
Return AliasNameAttribute.GetAliasName(CType(findValue, [Enum]))
End Function
End Class
Imports System.Reflection
<AttributeUsage(AttributeTargets.All)> _
Friend Class NameAttribute
Inherits Attribute
Private _name As String
Public Property Name() As String
Get
Return Me._name
End Get
Private Set(ByVal value As String)
Me._name = value
End Set
End Property
Public Sub New(ByVal name As String)
Me.Name = name
End Sub
Public Shared Function GetName(ByVal enumValue As [Enum]) As String
Dim enumType As Type = enumValue.[GetType]()
Dim enumName As String = [Enum].GetName(enumType, enumValue)
If enumName Is Nothing Then
Return Nothing
Else
Return GetName(enumType.GetField(enumName))
End If
End Function
Private Shared Function GetName(ByVal type As MemberInfo) As String
Dim attributes As Attribute()
attributes = TryCast(type.GetCustomAttributes(GetType(NameAttribute), True), Attribute())
If attributes Is Nothing OrElse attributes.Length = 0 Then
Return Nothing
End If
Dim nameAttribute As NameAttribute = TryCast(attributes(0), NameAttribute)
Return nameAttribute.Name
End Function
End Class
Imports System.Reflection
<AttributeUsage(AttributeTargets.All)> _
Friend Class AliasNameAttribute
Inherits Attribute
Private _aliasName As String
Public Property AliasName() As String
Get
Return Me._aliasName
End Get
Private Set(ByVal value As String)
Me._aliasName = value
End Set
End Property
Public Sub New(ByVal aliasName As String)
Me.AliasName = aliasName
End Sub
Public Shared Function GetAliasName(ByVal enumValue As [Enum]) As String
Dim enumType As Type = enumValue.GetType
Dim enumName As String = [Enum].GetName(enumType, enumValue)
If enumName Is Nothing Then
Return Nothing
Else
Return GetAliasName(enumType.GetField(enumName))
End If
End Function
Private Shared Function GetAliasName(ByVal type As MemberInfo) As String
Dim attributes As Attribute()
attributes = TryCast(type.GetCustomAttributes(GetType(AliasNameAttribute), True), Attribute())
If attributes Is Nothing OrElse attributes.Length = 0 Then
Return Nothing
End If
Dim nameAttribute As AliasNameAttribute = TryCast(attributes(0), AliasNameAttribute)
Return nameAttribute.AliasName
End Function
End Class
使うときはConstantクラスのCreateListメソッドのパラメータに列挙体のTypeを指定します。
With Me.cboDayOfWeekLong
.ValueMember = "Key"
.DisplayMember = "Value"
.BeginUpdate()
.DataSource = Constant.CreateList(GetType(Constant.DayOfWeek))
.EndUpdate()
.SelectedValue = Constant.DayOfWeek.Sat
End With
With Me.cboDayOfWeekShort
.ValueMember = "Key"
.DisplayMember = "Value"
.BeginUpdate()
.DataSource = Constant.CreateAliasList(GetType(Constant.DayOfWeek))
.EndUpdate()
.SelectedValue = CType(4, Constant.DayOfWeek)
End With
Dim findValue As Constant.DayOfWeek = CType(2, Constant.DayOfWeek)
Dim name As String = Constant.GetName(GetType(Constant.DayOfWeek), findValue)
Dim aliasName As String = Constant.GetAliasName(GetType(Constant.DayOfWeek), findValue)