Как указать требование проверки для пользователей моего класса? - PullRequest
3 голосов
/ 07 октября 2008

Я реализую класс, который оборачивается вокруг XML-документа с очень строго определенной схемой. Я не контролирую схему.

Одним из свойств в классе является значение элемента, которое, как указывает схема, должно соответствовать определенному регулярному выражению. В установщике для свойства, если строка не соответствует выражению, я выбрасываю исключение.

Мой вопрос: как я могу лучше сообщить пользователям моего класса о требованиях к этой области? Есть ли атрибут, который я могу использовать? XML-комментарии (чтобы они отображались в intellisense)? Должен ли я сделать что-то другое, кроме как бросить исключение? Какие еще варианты у меня есть?

Ответы [ 5 ]

1 голос
/ 07 октября 2008

XmlComments может помочь, если вы отправляете их вместе со своей сборкой, но я бы сказал, что вам лучше выбросить исключения, если требования не выполнены, и сделать сообщение об исключении как можно более подробным. Я также выбрасываю исключения (опять же с большим количеством деталей), если требование не выполняется, когда пользователь вызывает и методы / свойства полагаются на свойство.

На самом деле вы мало что можете сделать, чтобы кто-то, использующий код, не допустил ошибку с первого раза, но вы должны быть максимально ясны, когда ошибка действительно возникает, о том, как ее исправить.

0 голосов
/ 08 октября 2008

Независимо от того, использую я это или нет, реализация класса MatchedString выглядит забавно. Итак, вот оно:

Public Class MatchedString
    Public Enum InvalidValueBehaviors
        SetToEmpty
        AllowSetToInvalidValue
        DoNothing
    End Enum

    Public Sub New(ByVal Expression As String)
        Me.expression = Expression
        exp = New Regex(Me.expression)
    End Sub

    Public Sub New(ByVal Description As String, ByVal Expression As String)
        Me.expression = Expression
        exp = New Regex(Me.expression)
        _expressiondescription = Description
    End Sub

    Public Sub New(ByVal Expression As String, ByVal ThrowOnInvalidValue As Boolean, ByVal InvalidValueBehavior As InvalidValueBehaviors)
        Me.expression = Expression
        exp = New Regex(Me.expression)
        Me.ThrowOnInvalidValue = ThrowOnInvalidValue
        Me.InvalidValueBehavior = InvalidValueBehavior
    End Sub

    Public Sub New(ByVal Description As String, ByVal Expression As String, ByVal ThrowOnInvalidValue As Boolean, ByVal InvalidValueBehavior As InvalidValueBehaviors)
        Me.expression = Expression
        exp = New Regex(Me.expression)
        _expressiondescription = Description
        Me.ThrowOnInvalidValue = ThrowOnInvalidValue
        Me.InvalidValueBehavior = InvalidValueBehavior
    End Sub

    Private exp As Regex
    Private expression As String

    Public ReadOnly Property MatchExpression() As String
        Get
            Return expression
        End Get
    End Property

    Public ReadOnly Property ExpressionDescription() As String
        Get
            Return _expressiondescription
        End Get
    End Property
    Private _expressiondescription As String

    Public Function CheckIsMatch(ByVal s As String)
        Return exp.IsMatch(s)
    End Function

    Public Property ThrowOnInvalidValue() As Boolean
        Get
            Return _thrownoninvalidvalue
        End Get
        Set(ByVal value As Boolean)
            _thrownoninvalidvalue = value
        End Set
    End Property
    Private _thrownoninvalidvalue = True

    Public Property InvalidValueBehavior() As InvalidValueBehaviors
        Get
            Return _invalidvaluebehavior
        End Get
        Set(ByVal value As InvalidValueBehaviors)
            _invalidvaluebehavior = value
        End Set
    End Property
    Private _invalidvaluebehavior As InvalidValueBehaviors = InvalidValueBehaviors.DoNothing

    Public Property Value() As String
        Get
            Return _value
        End Get
        Set(ByVal value As String)
            If value Is Nothing Then value = "" 'Never set to Nothing

            If CheckIsMatch(value) Then
                _value = value
            Else
                Select Case InvalidValueBehavior
                    Case InvalidValueBehaviors.AllowSetToInvalidValue
                        _value = value
                    Case InvalidValueBehaviors.SetToEmpty
                        _value = ""
                End Select

                If ThrowOnInvalidValue Then
                    Throw New ArgumentOutOfRangeException(String.Format("String: {0} does not match expression: {1}", value, MatchExpression))
                End If
            End If
        End Set
    End Property
    Private _value As String = ""

    Public Overrides Function ToString() As String
        Return _value
    End Function
End Class
0 голосов
/ 07 октября 2008

Спасибо за совет.

Одной идеей, о которой я подумал, было создание нового класса с именем что-то вроде MatchedString для реализации ограничения.

У него будет конструктор, который требует строку регулярного выражения, и после построения выражение будет доступно пользователям только через свойство только для чтения. Тогда у него будет свойство value, которое пользователи могут установить, которое будет проверять соответствие выражению в установщике.

Я подумал, что тогда я мог бы также создать параметры для различных вариантов поведения, которые будут использоваться при сбое проверки в перечислении, и позволить пользователю указать, что он хочет:

  • установить в пустую строку
  • установить пустую строку и выдать исключение
  • установить неверное значение в любом случае
  • установить неверное значение в любом случае и выдать исключение
  • просто выбросить исключение
  • ничего не делать

Кроме того, я думал, что это позволит моему классному пользователю выполнить некоторые базовые тесты, не дублируя объект RegEx в своем собственном коде. Добавьте неявные преобразования в / из строкового типа, и он должен быть интуитивно понятен для пользователей класса.

Есть мысли по этому поводу?

0 голосов
/ 07 октября 2008

Либо документация вашего кода должна соответствовать требованиям, либо документация для схемы должна объяснять требования. Вы ничего не можете сделать для того, кто не потрудится исследовать код, который они собираются использовать.

0 голосов
/ 07 октября 2008

Документируйте это в комментариях XML и сгенерируйте исключение. Сделайте сообщение явным:

"Элемент должен совпадать / регулярное выражение /";

Это все, что вы можете сделать.

...