Combining code contracts and regex

梦想与她 提交于 2019-12-14 00:35:45

问题


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!


回答1:


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.




回答2:


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.




回答3:


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.



来源:https://stackoverflow.com/questions/5263282/combining-code-contracts-and-regex

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!