gpt4 book ai didi

c# - 真的很喜欢 C# 中的 CodeContracts

转载 作者:IT王子 更新时间:2023-10-29 03:45:47 27 4
gpt4 key购买 nike

我终于 catch 了添加到 .NET 3.5/4.0 框架中的所有新功能。最近几天我一直在使用 CodeContracts,我真的很努力地喜欢它们。我很好奇其他人如何看待 C# 中的 CodeContracts 实现?具体来说,人们如何组织接口(interface)的契约类、契约不变量的契约方法等?

我喜欢契约(Contract)提供的验证,乍一看它们看起来很棒。通过几行简单的代码,我什至可以在运行代码之前进行一些不错的构建检查。不幸的是,我很难克服在 C# 中实现代码契约的方式的感觉,它们使我的代码变得困惑,而不是记录契约。为了充分利用契约(Contract),我在代码中加入了假设和断言等(我知道有些人会说这是一件好事);但正如我在下面的一些示例中所展示的那样,它将一行简单的代码变成了 4 或 5 行,并且在我看来并没有真正增加替代方法(即断言、异常等)的足够值(value)。

目前,我最大的挫折是:

接口(interface)契约:

[ContractClass(typeof(IInterfaceContract))]
public interface IInterface
{
Object Method(Object arg);
}

[ContractClassFor(typeof(IInterface))]
internal abstract class IInterfaceContract
{
private IInterfaceContract() { }

Object IInterface.Method(Object arg)
{
Contract.Requires(arg != null);
Contract.Ensures(Contract.Result<Object>() != null);
return default(Object);
}
}

这对我来说感觉像是一个障碍,我希望有一种更清晰的方式来记录需求,无论是通过属性还是某种形式的内置语言支持。事实上,我必须实现一个实现我的接口(interface)的抽象类,这样我才能指定契约(Contract),这充其量看起来很乏味。

代码膨胀:

typeof(Action<>).MakeGenericType(typeof(Object);

需要几个假设来验证现成的信息。我很欣赏分析器只知道它在 Type 上运行,因此必须在有限的知识上工作,但仍然让我感到沮丧的是,一行代码需要我重新编写为

var genericAction = typeof(Action<>);

Contract.Assume(genericAction.IsGenericType);
Contract.Assume(genericAction.GetGenericArguments().Length == 1);

genericAction.MakeGenericType(typeof(Object));

只是为了将事情记录在案(是的,我知道我可以使用 ContractVerificationAttribute 为方法/类等关闭此功能,或使用 SuppressMessageAttribbute 来针对特定消息,但这似乎达不到目的,因为您的代码很快就会被压制等等

另外,举个例子

  public class MyClass
: IInterface
{
private readonly Object _obj;

public Object Property
{
get
{
Contract.Ensures(Contract.Result<Object>() != null);
return _obj;
}
}

public MyClass(Object obj)
{
Contract.Requires(obj != null);

_obj = obj;
}
}

obj要求不为null,并且设置为只读字段,不可更改,但我仍然需要在我的类中添加一个“标记”方法,以便证明我的属性要求不返回null :

[ContractInvariantMethod]
private void ObjectInvariant()
{
Contract.Invariant(_obj != null);
}

还有更多,但我想我可能已经说得够多了,我真的很感激比我聪明得多的人的洞察力来帮助我“喜欢”代码契约并让这种代码困惑的感觉消失。任何关于如何更好地构建代码、解决不稳定问题等的见解都将不胜感激。

谢谢!

最佳答案

This feels like such a cludge to me, I wish there was a cleaner way to document requirements, either via attributes or some form of built in language support.

CC 团队表示,仅使用属性还不够强大,因为您不能在其中包含诸如 lambda 之类的东西。它们可以包含[NotNull]之类的东西,但有chosen not to do so因为他们试图让 CC 尽可能通用。

CC 是一个库(而不是扩展 C# 的一部分)的一个原因是它受所有 .NET 语言的支持。

您可以阅读更多关于团队的推理here .

就实际使用而言,到目前为止,我一直将我的接口(interface)契约保存在与接口(interface)相同的文件中,这意味着它们都记录在同一个地方。这是应该改进的地方:)

Code Bloat [...]

您的第二个投诉可能是可以实现的 - 我建议将其发布在 the code contracts forum 上. (编辑:似乎有人 already has ,但还没有答案。)

但是,情况总是不明确的契约(Contract)需要围绕它们进行更多假设。如果您在 .NET 框架中遇到这种情况,您可以请求将契约(Contract)添加到 Missing Contracts on Libraries thread 中。 .

In addition, taking a case like [...]

has been addressed .如果你有一个自动属性,你只需要添加一个非空不变量,就会生成前置/后置条件:

public class MyClass : IInterface
{
private Object Property { get; set; }

[ContractInvariantMethod]
private void Invariants()
{
Contract.Invariant(Property != null);
}
}

无论如何,您最终可能会得到类的其他不变量,所以这没什么大不了的。

关于c# - 真的很喜欢 C# 中的 CodeContracts,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3077933/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com