LoginSignup
0
1

More than 1 year has passed since last update.

VB.Netでカスタム属性を作成

Posted at

背景

プロパティのまとまったクラスを使用し、CSV出力をしたいが、
プロパティ名を全て記載してCSV出力のためのファイルを作るのは手間がかかるし、
1つ追加する度にソースの変更が発生してしまう。
ということで、プロパティに順番のカスタム属性を付与し、
その順番順にForeachで繰り返すことでプロパティの値を取得するソースを作成しました。

目次

ソースコード全文は以下の通りです。

ソースコードの解説について記載しています。

ソースコード

Propertyクラス

''' <summary>
''' CSV用項目
''' </summary>
Public Class CsvProperty
    ' ヘッダー区分
    <Sort(0)>
    Property HeaderKbn As String

    ' ID
    <Sort(1)>
    Property Id As Integer

    ' 項目1
    <Sort(2)>
    Property Item1 As String

    ' 項目2
    <Sort(3)>
    Property Item2 As String

    ' 項目3
    <Sort(4)>
    Property Item3 As String
End Class

カスタム属性クラス

''' <summary>
''' カスタム属性
''' </summary>
<AttributeUsage(AttributeTargets.Property, AllowMultiple:=False, Inherited:=False)>
Public Class SortAttribute
    Inherits Attribute
    Private index As Integer
    Public Sub New(prmIndex As Integer)
        index = prmIndex
    End Sub
    Public ReadOnly Property SortIndex As Integer
        Get
            Return index
        End Get
    End Property
End Class

メイン

''' <summary>
''' メイン
''' </summary>
Public Shared Sub Main()
    ' テストデータ作成
    Dim csvList As New List(Of CsvProperty)

    Dim csvItems1 As New CsvProperty
    csvItems1.HeaderKbn = "H"
    csvItems1.Id = 1
    csvItems1.Item1 = "テスト項目1-1"
    csvItems1.Item2 = "テスト項目1-2"
    csvItems1.Item3 = "テスト項目1-3"
    csvList.Add(csvItems1)

    Dim csvItems2 As New CsvProperty
    csvItems2.HeaderKbn = "D"
    csvItems2.Id = 2
    csvItems2.Item1 = "テスト項目2-1"
    csvItems2.Item2 = "テスト項目2-2"
    csvItems2.Item3 = "テスト項目2-3"
    csvList.Add(csvItems2)

    Dim csvFilePath As String = "C:\CSV\CSVプロパティカスタム.csv"
    If IO.File.Exists(csvFilePath) Then
        ' 同名ファイルが既に存在する場合、削除
        IO.File.Delete(csvFilePath)
    End If

    ' CSVファイル書き込み
    Dim csvFile As New System.IO.StreamWriter(csvFilePath, True, Text.Encoding.GetEncoding("Shift_JIS"))

    ' CSV出力順にリスト作成
    Dim sortCsvList As List(Of String) =
        GetType(CsvProperty).GetProperties().
        OrderBy(Function(a) CType(Attribute.GetCustomAttribute(a, GetType(SortAttribute)), SortAttribute).SortIndex).
        Select(Function(a) a.Name).
        ToList()

    ' テストデータのリスト数分繰り返す
    For Each csvItems As CsvProperty In csvList
        Dim lastCnt As Integer = sortCsvList.Count
        Dim cnt As Integer = 0

        ' csv項目数分繰り返す
        For Each sortCsvItem As String In sortCsvList
            csvFile.Write("""" & CallByName(csvItems, sortCsvItem, CallType.Get) & """")
            If lastCnt - 1 > cnt Then
                csvFile.Write(","c)
            End If
            cnt += 1
        Next

        ' 改行する
        csvFile.Write(vbCrLf)
    Next

    ' CSVファイル書き込み終了
    csvFile.Close()
End Sub

出力CSV

ソースコードの詳細

Propertyクラス

    <Sort(0)>
    Property HeaderKbn As String
  • <Sort(X)>がカスタム属性
  • <SortAttribute(X)>でも記載できる

カスタム属性クラス

<AttributeUsage(AttributeTargets.Property, AllowMultiple:=False, Inherited:=False)>
  • AttributeUsage
    • カスタム属性の適用方法を制御できる属性
  • AllowMultiple
    • カスタム属性が複数回適用できる(TRUE)か、できない(FALSE)を指定できる
  • Inherited
    • カスタム属性から派生するクラスを継承する(TRUE)か、しない(FALSE)を指定できる
Public Class SortAttribute
    Inherits Attribute
    Private index As Integer
    Public Sub New(prmIndex As Integer)
        index = prmIndex
    End Sub
    Public ReadOnly Property SortIndex As Integer
        Get
            Return index
        End Get
    End Property
End Class
  • <Sort(X)>のXの値がSETされ、SortIndexでGETできる

メイン

    ' CSV出力順にリスト作成
    Dim sortCsvList As List(Of String) =
        GetType(CsvProperty).GetProperties().
        OrderBy(Function(a) CType(Attribute.GetCustomAttribute(a, GetType(SortAttribute)), SortAttribute).SortIndex).
        Select(Function(a) a.Name).
        ToList()
  • SortIndex順にPropertyクラスを並び替える
  • プロパティ名だけのリストを作成する
    csvFile.Write("""" & CallByName(csvItems, sortCsvItem, CallType.Get) & """")
  • CallByNameを使用し、プロパティ名からプロパティに設定されている値を取得する
    例)以下のデータから、HeaderKbnのプロパティ名を指定し、
      "D"という値を取得する
    image.png

参考資料

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1