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

Jou*_*aas 2 .net c# regex code-contracts

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

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
    }
}
Run Code Online (Sandbox Code Playgroud)

非常直截了当.但是,这会抛出一个不可读的异常,另一个说"Member SimpleClass.IsValid的可见性低于封闭方法SimpleClass.#ctor(System.String)".为什么这是非法的?我应该将正则表达式复制/粘贴到两种方法中吗?这似乎与正确相反.请帮我理解!

jas*_*son 5

只需标记IsValidpublic,你会没事的.公共表面合同的所有"组成部分"也必须是公开的,否则呼叫者无法检查合同是否满足.

@ AI-CII我理解这一点,但这也是一个设计缺陷,向消费者展示实施细节.

  1. 公共方法的合同不是实现细节.A Contract.Requires说:"嘿,我要求我为你做一些工作." 如果呼叫者看不到"此",呼叫者如何验证合同是否满足?

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


por*_*ges 5

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

public SimpleClass(Email address)
{
    // no need to check, it must be valid :)
}
Run Code Online (Sandbox Code Playgroud)

...然后将所有验证逻辑封装在Email类中.你仍然会有关于验证的"字符串格式"问题,但我认为更好的习惯是创建一个名为的方法Email.TryParse,并按照它的方式进行计算int.TryParse.