I'm implementing a class that wraps around an xml document with a very strictly defined schema. I don't control the schema.
我正在实现一个包含非常严格定义的模式的xml文档的类。我不控制架构。
One of the properties in the class is for an element value that the schema indicates must match a certain regular expression. In the setter for the property, if a string doesn't match the expression I'm throwing an exception.
类中的一个属性是模式指示的元素值必须与某个正则表达式匹配。在属性的setter中,如果字符串与表达式不匹配,则抛出异常。
My question is, how can I better communicate to users of my class the requirements for this field? Is there an attribute I can use? Xml comments (so it shows up in intellisense)? Should I do something other than thrown an exception? What other options do I have?
我的问题是,我怎样才能更好地与班级用户沟通这个领域的要求?我可以使用哪个属性? Xml评论(因此它显示在intellisense中)?除了抛出异常,我应该做些什么吗?我还有其他选择吗?
5 个解决方案
#1
1
XmlComments may help if you ship them with your assembly, but I would say that you are best off throwing exceptions if the requirements are not met, and making the exception message as detailed as possible. I would also throw exceptions (again with lots of detail) if the requirement is not met when the user calls and methods/properties the rely on the property.
如果你使用你的程序集发送它们,XmlComments可能会有所帮助,但我会说如果不满足要求你最好抛出异常,并尽可能详细地说明异常消息。如果在用户调用和依赖于属性的方法/属性时不满足要求,我也会抛出异常(同样有很多细节)。
There isn't really much you can do to keep someone using the code from making the mistake the first time, but you should be as clear as possible when the mistake does occur about how to correct it.
你没有太多可以做的事情来阻止某人使用代码第一次犯错误,但是当你发现错误的时候你应该尽可能清楚地知道如何纠正它。
#2
0
Document it in the XML comments, and throw an exception. Make the message explicit:
在XML注释中记录它,并抛出异常。使消息显式:
"Element <elementname> must match /regex/";
“Element
That's about all you can do.
这就是你所能做的一切。
#3
0
Either your code's documentation should address requirements, or the documentation for the schema should explain the requirements. You can't do anything for someone who doesn't bother to research the code they're about to use.
您的代码文档应该满足要求,或者模式的文档应该解释要求。你不能为那些懒得研究他们即将使用的代码的人做任何事情。
#4
0
Thanks for the advice.
感谢您的建议。
One idea I had while thinking about this was creating a new class named something like MatchedString to enforce the constraint.
我在考虑这个问题时想到的一个想法是创建一个名为MatchedString的新类来强制执行约束。
It'd have a constructor that required a regex string, and after construction the expression would only be exposed to users via a read-only property. Then it would have a value property that users could set that would check against the expression in the setter.
它有一个需要正则表达式字符串的构造函数,构造之后表达式只会通过只读属性向用户公开。然后它将有一个value属性,用户可以设置它将检查setter中的表达式。
My thought was that I could then also create options for different behaviors to use when the validation failed in an enum, and let the user specify which they want:
我的想法是,我还可以创建用于在枚举中验证失败时使用的不同行为的选项,并让用户指定他们想要的内容:
- set to empty string
- set to empty string and throw exception
- set bad value anyway
- set bad value anyway, and throw excpetion
- just throw exception
- do nothing
设置为空字符串
设置为空字符串并抛出异常
无论如何设置坏的价值
无论如何设置坏的价值,并抛出刺激
只是抛出异常
Also, I was thinking that this would allow my class user to do some basic tests without having to duplicate the RegEx object in their own code. Throw in implicit conversions to/from the string type, and it should be intuitive to class users.
此外,我认为这将允许我的类用户进行一些基本测试,而无需在他们自己的代码中复制RegEx对象。对字符串类型进行隐式转换,对类用户来说应该是直观的。
Any thoughts on this?
有什么想法吗?
#5
0
Whether or not I use it, implementing a MatchedString class looked like fun. So here it is:
无论我是否使用它,实现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
#1
1
XmlComments may help if you ship them with your assembly, but I would say that you are best off throwing exceptions if the requirements are not met, and making the exception message as detailed as possible. I would also throw exceptions (again with lots of detail) if the requirement is not met when the user calls and methods/properties the rely on the property.
如果你使用你的程序集发送它们,XmlComments可能会有所帮助,但我会说如果不满足要求你最好抛出异常,并尽可能详细地说明异常消息。如果在用户调用和依赖于属性的方法/属性时不满足要求,我也会抛出异常(同样有很多细节)。
There isn't really much you can do to keep someone using the code from making the mistake the first time, but you should be as clear as possible when the mistake does occur about how to correct it.
你没有太多可以做的事情来阻止某人使用代码第一次犯错误,但是当你发现错误的时候你应该尽可能清楚地知道如何纠正它。
#2
0
Document it in the XML comments, and throw an exception. Make the message explicit:
在XML注释中记录它,并抛出异常。使消息显式:
"Element <elementname> must match /regex/";
“Element
That's about all you can do.
这就是你所能做的一切。
#3
0
Either your code's documentation should address requirements, or the documentation for the schema should explain the requirements. You can't do anything for someone who doesn't bother to research the code they're about to use.
您的代码文档应该满足要求,或者模式的文档应该解释要求。你不能为那些懒得研究他们即将使用的代码的人做任何事情。
#4
0
Thanks for the advice.
感谢您的建议。
One idea I had while thinking about this was creating a new class named something like MatchedString to enforce the constraint.
我在考虑这个问题时想到的一个想法是创建一个名为MatchedString的新类来强制执行约束。
It'd have a constructor that required a regex string, and after construction the expression would only be exposed to users via a read-only property. Then it would have a value property that users could set that would check against the expression in the setter.
它有一个需要正则表达式字符串的构造函数,构造之后表达式只会通过只读属性向用户公开。然后它将有一个value属性,用户可以设置它将检查setter中的表达式。
My thought was that I could then also create options for different behaviors to use when the validation failed in an enum, and let the user specify which they want:
我的想法是,我还可以创建用于在枚举中验证失败时使用的不同行为的选项,并让用户指定他们想要的内容:
- set to empty string
- set to empty string and throw exception
- set bad value anyway
- set bad value anyway, and throw excpetion
- just throw exception
- do nothing
设置为空字符串
设置为空字符串并抛出异常
无论如何设置坏的价值
无论如何设置坏的价值,并抛出刺激
只是抛出异常
Also, I was thinking that this would allow my class user to do some basic tests without having to duplicate the RegEx object in their own code. Throw in implicit conversions to/from the string type, and it should be intuitive to class users.
此外,我认为这将允许我的类用户进行一些基本测试,而无需在他们自己的代码中复制RegEx对象。对字符串类型进行隐式转换,对类用户来说应该是直观的。
Any thoughts on this?
有什么想法吗?
#5
0
Whether or not I use it, implementing a MatchedString class looked like fun. So here it is:
无论我是否使用它,实现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