结合代码契约和正则表达式
所以我有一个非常简单的类,其中一个字符串作为属性。该字符串必须具有一定的模式。我正在尝试使用代码契约来强制执行此操作。该类看起来像这样:
class SimpleClass
{
public Property { get; set; }
public SimpleClass(string prop)
{
Contract.Requires(IsValid(prop));
this.Property = prop;
}
[ContractInvariantMethod]
void ObjectInvariant()
{
Contract.Invariant(IsValid(Property));
}
bool IsValid(string arg)
{
// Use regex to check if arg is a valid string
}
}
非常简单。但是,这会引发一个不可读的异常,而另一个异常则表示“成员 SimpleClass.IsValid 的可见性低于封闭方法 SimpleClass.#ctor(System.String)”。为什么这是非法的?我应该将正则表达式复制/粘贴到这两种方法中吗?这似乎与正确的相反。请帮我理解!
So I have a very simple class with one string as property. This string has to have a certain pattern. I'm trying to enforce this using code contracts. The class looks something like this:
class SimpleClass
{
public Property { get; set; }
public SimpleClass(string prop)
{
Contract.Requires(IsValid(prop));
this.Property = prop;
}
[ContractInvariantMethod]
void ObjectInvariant()
{
Contract.Invariant(IsValid(Property));
}
bool IsValid(string arg)
{
// Use regex to check if arg is a valid string
}
}
Very straightforward. However, this throws an unreadable exception and another one saying that 'Member SimpleClass.IsValid has less visibility than the enclosing method SimpleClass.#ctor(System.String)'. Why is this illegal? Should I copy/paste the regex into both methods? That seems to be the opposite of right. Please help me understand!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
另一种方法是避免“原始痴迷”并使用适合您的目的的类,例如:
...然后将所有验证逻辑封装在 Email 类中。您仍然会遇到有关验证的“字符串格式”问题,但我认为更好的习惯用法是创建一个名为
Email.TryParse
的方法,并按照int 的方式设计它.尝试解析
。Another way is avoid 'primitive obsession' and use a class tailored to your purpose, e.g.:
... and then encapsulate all your validation logic in the Email class. You'll still have the "string format" issues about validation, but I think a better idiom for this is to create a method called
Email.TryParse
, and fashion it along the lines ofint.TryParse
.只需将
IsValid
标记为public
就可以了。公共表面合同的所有“组件”也必须是公开的,否则调用者无法检查合同是否得到满足。公共方法上的契约不是实现细节。
Contract.Requires
表示“嘿,我要求这是真的,以便我为您做一些工作。”如果“this”对调用者不可见,那么调用者如何验证契约是否得到满足?您没有公开方法
IsValid
的实现细节,您只是公开了被调用者完成其工作必须满足的条件。Just mark
IsValid
aspublic
and you'll be fine. All "components" of a public surface contract have to be public as well, otherwise there is no way for a caller to check that the contract is satisfied.A contract on a public method is not an implementation detail. A
Contract.Requires
says "hey, I require this to be true for me to do some work for you." If "this" isn't visible to the caller, how can the caller verify that the contract is satisfied?You aren't exposing the implementation details of the method
IsValid
, you are only exposing what must be satisfied for the callee to do its job.正如杰森已经说过的,代码契约要求该方法是公开的,因为您已经通过异常消息自己弄清楚了。
但我明白,仅仅将其公开感觉是不对的。也许正则表达式条件可以封装到辅助类的静态全局函数中?
例如,如果要检查一个字符串是否是一个有效的 URL。
这让我很感兴趣,所以我开始进行一些谷歌搜索。有解决办法!尽管我仍然更喜欢尽可能使用静态方法的辅助类。
它称为代码合约缩写。但是,您需要自己将源文件包含到您的项目中。
As Jason already stated, Code Contracts requires the method to be public as you already figured out yourself thanks to the exception message.
I understand however that simply making it public doesn't feel right. Perhaps the regex condition can be encapsulated to a static global function of a helper class?
E.g. If it were to check whether a string is a valid URL.
This interested me so I started doing some googling. There is a solution! Although I would still prefer the helper class with the static method where possible.
It is called Code Contract Abbreviators. You need to include the sourcefile to your project yourself however.