【VB.NET】判定ロジック

''' <summary>
''' シンプルな条件評価クラス
''' </summary>
Public Class SimpleEvaluator

    ''' <summary>
    ''' カンマ区切りの条件をチェックする
    ''' 条件例: "ToUpper:Name:TANAKA,Length:Address:5"
    ''' </summary>
    Public Shared Function CheckConditions(target As Person, Optional targetCheck As PersonCheck? = Nothing, Optional conditions As String = "") As Boolean
        ' 条件が空ならTrue
        If String.IsNullOrWhiteSpace(conditions) Then
            Return True
        End If

        ' カンマで条件を分割
        Dim conditionArray() As String = conditions.Split(","c)

        ' すべての条件をチェック
        For Each condition As String In conditionArray
            ' 1つでも条件を満たさなければFalse
            If Not CheckOneCondition(target, targetCheck, condition.Trim()) = True Then
                Return False
            End If
        Next

        ' すべてOKならTrue
        Return True
    End Function

    ''' <summary>
    ''' 1つの条件をチェックする
    ''' 条件例: "ToUpper:Name:TANAKA"
    ''' </summary>
    Private Shared Function CheckOneCondition(target As Person, targetCheck As PersonCheck?, condition As String) As Boolean
        ' コロンで分割: メソッド名:プロパティ名:期待値
        Dim parts() As String = condition.Split(":"c)

        ' 3つに分割できなければエラー
        If parts.Length <> 3 Then
            Throw New Exception("条件の形式が正しくありません: " & condition)
        End If

        Dim methodName As String = parts(0).Trim()    ' メソッド名
        Dim propertyName As String = parts(1).Trim()  ' プロパティ名
        Dim expectedValue As String = parts(2).Trim() ' 期待する値

        ' メソッド名によってPersonCheckを使うか判定
        Dim usePersonCheck As Boolean = ShouldUsePersonCheck(methodName)

        ' プロパティの値を取得
        Dim propertyValue As String = ""
        If usePersonCheck Then
            ' PersonCheckを使用
            If targetCheck.HasValue Then
                propertyValue = GetPersonCheckValue(targetCheck.Value, propertyName)
            Else
                Throw New Exception("PersonCheckが必要ですが、指定されていません")
            End If
        Else
            ' Personを使用
            propertyValue = GetPropertyValue(target, propertyName)
        End If

        ' メソッドを実行して結果を取得
        Dim result As String = ExecuteMethod(propertyValue, methodName)

        ' 結果と期待値を比較
        Return result = expectedValue
    End Function

    ''' <summary>
    ''' メソッド名からPersonCheckを使うべきか判定
    ''' </summary>
    Private Shared Function ShouldUsePersonCheck(methodName As String) As Boolean
        Select Case methodName
            Case "IsTrue", "IsFalse", "CheckValue"
                Return True
            Case Else
                Return False
        End Select
    End Function

    ''' <summary>
    ''' Personのプロパティの値を取得する
    ''' </summary>
    Private Shared Function GetPropertyValue(target As Person, propertyName As String) As String
        Select Case propertyName
            Case "Name"
                Return target.Name
            Case "Address"
                Return target.Address
            Case "Age"
                Return target.Age.ToString()
            Case Else
                Throw New Exception("プロパティ名が不正です: " & propertyName)
        End Select
    End Function

    ''' <summary>
    ''' PersonCheckのプロパティの値を取得する
    ''' </summary>
    Private Shared Function GetPersonCheckValue(targetCheck As PersonCheck, propertyName As String) As String
        Dim intValue As Integer
        Select Case propertyName
            Case "Name"
                intValue = targetCheck.Name
            Case "Address"
                intValue = targetCheck.Address
            Case "Age"
                intValue = targetCheck.Age
            Case Else
                Throw New Exception("プロパティ名が不正です: " & propertyName)
        End Select

        ' 0と1をTrueとFalseに変換
        If intValue = 1 Then
            Return "True"
        Else
            Return "False"
        End If
    End Function

    ''' <summary>
    ''' メソッドを実行する
    ''' </summary>
    Private Shared Function ExecuteMethod(value As String, methodName As String) As String
        Select Case methodName
            ' 標準メソッド
            Case "ToUpper"
                Return value.ToUpper()
            Case "ToLower"
                Return value.ToLower()
            Case "Length"
                Return value.Length.ToString()
            Case "Trim"
                Return value.Trim()

            ' 独自メソッド
            Case "FirstChar"
                Return GetFirstChar(value)
            Case "LastChar"
                Return GetLastChar(value)
            Case "Reverse"
                Return ReverseString(value)
            Case "ContainsA"
                Return ContainsChar(value, "a")
            Case "IsNumeric"
                Return IsNumericValue(value)

            ' PersonCheck用メソッド
            Case "IsTrue"
                Return value ' Booleanの文字列をそのまま返す
            Case "IsFalse"
                ' Trueなら"False"、Falseなら"True"を返す(反転)
                If value = "True" Then
                    Return "False"
                Else
                    Return "True"
                End If
            Case "CheckValue"
                Return value ' Booleanの文字列をそのまま返す

            Case Else
                Throw New Exception("メソッド名が不正です: " & methodName)
        End Select
    End Function

    ' === 独自メソッド ===

    ''' <summary>
    ''' 最初の1文字を取得
    ''' </summary>
    Private Shared Function GetFirstChar(value As String) As String
        If String.IsNullOrEmpty(value) Then Return ""
        Return value.Substring(0, 1)
    End Function

    ''' <summary>
    ''' 最後の1文字を取得
    ''' </summary>
    Private Shared Function GetLastChar(value As String) As String
        If String.IsNullOrEmpty(value) Then Return ""
        Return value.Substring(value.Length - 1, 1)
    End Function

    ''' <summary>
    ''' 文字列を反転
    ''' </summary>
    Private Shared Function ReverseString(value As String) As String
        If String.IsNullOrEmpty(value) Then Return ""
        Dim chars() As Char = value.ToCharArray()
        Array.Reverse(chars)
        Return New String(chars)
    End Function

    ''' <summary>
    ''' 指定した文字が含まれるか
    ''' </summary>
    Private Shared Function ContainsChar(value As String, searchChar As String) As String
        If value.Contains(searchChar) Then
            Return "True"
        Else
            Return "False"
        End If
    End Function

    ''' <summary>
    ''' 数値かどうか
    ''' </summary>
    Private Shared Function IsNumericValue(value As String) As String
        If IsNumeric(value) Then
            Return "True"
        Else
            Return "False"
        End If
    End Function

End Class

' ===== テスト用の構造体 =====
Public Structure Person
    Public Name As String
    Public Address As String
    Public Age As Integer
End Structure

Public Structure PersonCheck
    Public Name As Integer      ' 0 = False, 1 = True
    Public Address As Integer   ' 0 = False, 1 = True
    Public Age As Integer       ' 0 = False, 1 = True
End Structure

' ===== テストコード =====
Module TestModule
    Sub Main()
        ' テストデータ
        Dim person As Person
        person.Name = "tanaka"
        person.Address = "Tokyo"
        person.Age = 30

        ' PersonCheckのテストデータ(0 = False, 1 = True)
        Dim personCheck As PersonCheck
        personCheck.Name = 1        ' True
        personCheck.Address = 0     ' False
        personCheck.Age = 1         ' True

        Console.WriteLine("=== Personのテスト ===")
        Console.WriteLine()

        ' テスト1: 名前を大文字にする
        Dim test1 As Boolean = SimpleEvaluator.CheckConditions(person, Nothing, "ToUpper:Name:TANAKA")
        Console.WriteLine("テスト1 (ToUpper): " & test1) ' True

        ' テスト2: 住所の長さ
        Dim test2 As Boolean = SimpleEvaluator.CheckConditions(person, Nothing, "Length:Address:5")
        Console.WriteLine("テスト2 (Length): " & test2) ' True

        ' テスト3: 複数条件
        Dim test3 As Boolean = SimpleEvaluator.CheckConditions(person, Nothing, "ToUpper:Name:TANAKA,Length:Address:5")
        Console.WriteLine("テスト3 (複数条件): " & test3) ' True

        Console.WriteLine()
        Console.WriteLine("=== PersonCheckのテスト ===")
        Console.WriteLine()

        ' テスト4: PersonCheckのNameがTrueかチェック
        Dim test4 As Boolean = SimpleEvaluator.CheckConditions(person, personCheck, "IsTrue:Name:True")
        Console.WriteLine("テスト4 (IsTrue Name): " & test4) ' True

        ' テスト5: PersonCheckのAddressがFalseかチェック
        Dim test5 As Boolean = SimpleEvaluator.CheckConditions(person, personCheck, "IsTrue:Address:False")
        Console.WriteLine("テスト5 (IsTrue Address): " & test5) ' True

        ' テスト6: PersonCheckのAgeがTrueかチェック
        Dim test6 As Boolean = SimpleEvaluator.CheckConditions(person, personCheck, "CheckValue:Age:True")
        Console.WriteLine("テスト6 (CheckValue Age): " & test6) ' True

        Console.WriteLine()
        Console.WriteLine("=== PersonCheckなしのテスト ===")
        Console.WriteLine()

        ' テスト7: PersonCheckなしでPersonのみ使用
        Dim test7 As Boolean = SimpleEvaluator.CheckConditions(person, Nothing, "ToUpper:Name:TANAKA,FirstChar:Address:T")
        Console.WriteLine("テスト7 (PersonCheckなし): " & test7) ' True

        Console.WriteLine()
        Console.WriteLine("=== テスト終了 ===")
        Console.ReadLine()
    End Sub
End Module

コメント

タイトルとURLをコピーしました