结合代码契约和正则表达式

发布于 2024-10-21 06:51:23 字数 640 浏览 1 评论 0原文

所以我有一个非常简单的类,其中一个字符串作为属性。该字符串必须具有一定的模式。我正在尝试使用代码契约来强制执行此操作。该类看起来像这样:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

苏璃陌 2024-10-28 06:51:23

另一种方法是避免“原始痴迷”并使用适合您的目的的类,例如:

public SimpleClass(Email address)
{
    // no need to check, it must be valid :)
}

...然后将所有验证逻辑封装在 Email 类中。您仍然会遇到有关验证的“字符串格式”问题,但我认为更好的习惯用法是创建一个名为 Email.TryParse 的方法,并按照 int 的方式设计它.尝试解析

Another way is avoid 'primitive obsession' and use a class tailored to your purpose, e.g.:

public SimpleClass(Email address)
{
    // no need to check, it must be valid :)
}

... 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 of int.TryParse.

深海夜未眠 2024-10-28 06:51:23

只需将 IsValid 标记为 public 就可以了。公共表面合同的所有“组件”也必须是公开的,否则调用者无法检查合同是否得到满足。

@AI-CII 我理解这一点,但这也将是一个设计缺陷,向消费者公开实现细节。

  1. 公共方法上的契约不是实现细节。 Contract.Requires 表示“嘿,我要求这是真的,以便我为您做一些工作。”如果“this”对调用者不可见,那么调用者如何验证契约是否得到满足?

  2. 您没有公开方法 IsValid 的实现细节,您只是公开了被调用者完成其工作必须满足的条件。

Just mark IsValid as public 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.

@AI-CII I understand that, but that would be a design flaw as well, exposing implementation details to consumers.

  1. 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?

  2. 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.

我为君王 2024-10-28 06:51:23

正如杰森已经说过的,代码契约要求该方法是公开的,因为您已经通过异常消息自己弄清楚了。

但我明白,仅仅将其公开感觉是不对的。也许正则表达式条件可以封装到辅助类的静态全局函数中?

例如,如果要检查一个字符串是否是一个有效的 URL。

UrlHelper.IsValidUrl( string 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.

UrlHelper.IsValidUrl( string 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文