C# 4.0 中的代码契约

发布于 2024-11-14 10:54:34 字数 641 浏览 4 评论 0原文

我做了一个这样的方法

class PersonCollection
{
  [Contracts.CanReturnNull]  //dont know if something like this exists?
  IPerson GetPerson(Guid personId)
  {
       if (this.persons.Contains(personId))
            return this.persons[personId];
       else
            return null;
  }
}

现在调用代码需要正确处理空值。有没有一种方法可以为所有调用者表达一个契约,即他们需要能够处理此方法返回的空值?

PersonCollection pc = new PersonCollection();
IPerson p = pc.GetPerson(anyId);
p.Name = "Hugo";  // here I want to have a curly line

我想要的是 p 被标记为潜在问题。

编辑 我刚刚修改了代码并添加了调用代码和预期的行为。我还添加了一个可能在 GetPerson 方法中不存在的属性

I made a method like this

class PersonCollection
{
  [Contracts.CanReturnNull]  //dont know if something like this exists?
  IPerson GetPerson(Guid personId)
  {
       if (this.persons.Contains(personId))
            return this.persons[personId];
       else
            return null;
  }
}

Now the calling code needs to handle the null value properly. Is there a way to express a contract for all callers that they need to be able to handle the null value returned by this method?

PersonCollection pc = new PersonCollection();
IPerson p = pc.GetPerson(anyId);
p.Name = "Hugo";  // here I want to have a curly line

What I want is that the p gets marked as potential problematic.

EDIT
I just modified the code and added the calling code and the expcected behaviour. Also I added an attribute that probalbly does not exists on the method GetPerson

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(2

如梦初醒的夏天 2024-11-21 10:54:34

代码契约不提供这样的功能,C#

代码契约也不只要求调用者在被调用方法的开始处遵守某些约束。这些就是所谓的前提
后置条件是被调用者的责任,它定义了被调用方法退出时程序的状态。

按契约设计是一种定义这些职责的方法,而不是告诉调用者应该如何处理由被调用方法引起的某些条件。

Code Contract does not provide such a feature, nor does C#

Code Contracts only requires from the caller to comply to certain constraints at the start of the called method. These are the so-called preconditions.
The postconditions are the responsibility of the callee, and defines what the state of the program will be on exit of the called method.

Design by Contract is a way to define these responsibilities, not to tell callers how they should handle certain conditions caused by the called method.

眉黛浅 2024-11-21 10:54:34

默认情况下,您似乎想要的事情(在阅读注释后)将会发生:

如果您在调用代码中启用代码契约,验证程序将认为 GetPerson() 的返回可以为 null。所以:

IPerson GetPerson(Guid personId)
{
   // no pre/post conditions
}

void PrintPerson(IPerson p)
{
   Contract.Requires(p != null);
   ...
}

void Foo()
{
     var p = GetPerson(id);
     PrintPerson(p);    // a warning here: can not verify p != null
}

而且,与问题完全无关,如果 people 是(像)字典,这通常会更有效:

IPerson GetPerson(Guid personId)
{
   Person p = null;

   this.persons.TryGetValue(personId, out p);
   return p;
}

What you seem to want (after reading the comments) will happen by default:

If you enable Code Contracts in the calling code, the verifier will consider that the return of GetPerson() can be null. So:

IPerson GetPerson(Guid personId)
{
   // no pre/post conditions
}

void PrintPerson(IPerson p)
{
   Contract.Requires(p != null);
   ...
}

void Foo()
{
     var p = GetPerson(id);
     PrintPerson(p);    // a warning here: can not verify p != null
}

And, totally irrelevant to the question, this will usually be more efficient if persons is (like) a Dictionary:

IPerson GetPerson(Guid personId)
{
   Person p = null;

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