标签: code-contracts

我们应该允许null/empty参数吗?

我最近与同事讨论过是否应该允许将null或空集合作为方法参数传递.我的感觉是,这会导致异常,因为它会破坏方法的"契约",即使它不一定会破坏方法的执行.这也具有"快速失败"的优点.我的同事辩称,这会导致代码乱丢"非空/非空"检查,即使它不重要.

我可以看到他的观点,但允许空或空参数让我感到不安.它可以通过延迟失败来隐藏问题的真正原因!

我们来看两个具体的例子:

1)鉴于我们有一个带有重叠(Interval)方法的Interval类,如果将null作为参数传递会发生什么?我的感觉是我们应该抛出一个IllegalArgumentException来让调用者知道某些东西可能是错误的,但我的同事觉得返回false是足够的,就像在他使用它的场景中一样,如果第二个Interval是是否为空(重要的是它们是否重叠).

2)给定一个像fetchByIds(Collection ids)这样的方法,如果提供一个空集合会发生什么?再一次,我想警告打电话者发生了异常情况,但我的同事只是收到一个空列表就好了,因为他再一次并不关心是否有任何ids.

被叫代码的责任在哪里结束?在这两种情况下,调用代码都不介意参数是null还是空,但在其他情况下,这可能指向可能的错误.一个方法是否只保证只要遵守先决条件就不会破坏,或者它是否应该尝试识别潜在的错误调用?

编辑:我看到了很多很好的答案,大多数人倾向于将其定义为合同/在文档中,并坚持使用它,但我希望你的意见何时允许它,何时不允许(如果有的话).在具体的例子中,你会做什么?鉴于90%的用途,没有验证输入将是正常的,你仍然会验证清除剩余的10%中的错误,或者你宁愿解决那些出现的问题,并避免不必要的空/空检查?

parameters null code-contracts

10
推荐指数
1
解决办法
863
查看次数

代码合同,forall和custom可枚举

我正在使用C#4.0和Code Contracts,我有自己的自定义GameRoomCollection : IEnumerable<GameRoom>.

我想确保,任何实例GameRoomCollection都不会包含null值元素.不过,我似乎无法做到这一点.我试图做一个简单明了的例子,而不是制定一般规则.这AllGameRooms是一个实例GameRoomCollection.

private void SetupListeners(GameRoom newGameRoom) {
  Contract.Requires(newGameRoom != null);
  //...
}
private void SetupListeners(Model model) {
    Contract.Requires(model != null);
    Contract.Requires(model.AllGameRooms != null);
    Contract.Assume(Contract.ForAll(model.AllGameRooms, g => g != null));
    foreach (GameRoom gameRoom in model.AllGameRooms)
        SetupListeners(gameRoom);//<= Warning: Code Contracts: Requires unproven: newGameRoom != null 
}
Run Code Online (Sandbox Code Playgroud)

任何人都可以看到,为什么我没有证明,那gameRoom不是null吗?

编辑:

在迭代之前添加对象的引用也不起作用:

IEnumerable<IGameRoom> gameRooms = model.AllGameRooms;
Contract.Assume(Contract.ForAll(gameRooms, g => g != null));
foreach (IGameRoom gameRoom in gameRooms)
    SetupListeners(gameRoom);//<= …
Run Code Online (Sandbox Code Playgroud)

c# enumerable code-contracts forall

10
推荐指数
1
解决办法
1393
查看次数

使用代码约定来定义不可变接口?

我可以使用代码约定来定义接口上的只读,不变属性吗?即实例化后总是产生相同值的属性?

.net c# code-contracts

10
推荐指数
1
解决办法
1208
查看次数

为什么.net异常没有被捕获?

考虑以下"安全"计划:

internal class Safe
{
    public static void SafeMethodWillNeverThrow()
    {
        try
        {
            var something = ThrowsNewException();
            Func<int, string> x = p => something.ToString();
        }
        catch (Exception)
        {
        }
    }

    private static object ThrowsNewException() 
    {
        throw new Exception();
    }

    public static void Main()
    {
        SafeMethodWillNeverThrow();
    }
}
Run Code Online (Sandbox Code Playgroud)

它永远不会以异常完成.但是为什么它在我运行时失败了?为什么SafeMethodWillNeverThrow()会抛出异常?

在测试此代码之前,请阅读以下答案.

.net exception-handling exception code-contracts

10
推荐指数
1
解决办法
932
查看次数

与接口的代码约定:"跳过方法调用.编译器将生成方法调用,因为该方法是有条件的...... [...]"

晚上好,

我刚开始玩Microsoft.Contracts(最新版本)并将其插入到示例界面之上,现在它看起来像这样:

namespace iRMA2.Core.Interfaces
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.Composition;
    using System.Diagnostics.Contracts;

    /// <summary>
    /// Base Interface declarations for iRMA2 Extensions
    /// </summary>
    [InheritedExport]
    [ContractClass(typeof(IiRMA2ExtensionContract))]
    public interface IiRMA2Extension
    {
        /// <summary>
        /// Gets the name.
        /// </summary>
        /// <value>The name of the Extension.</value>
        string Name { get; }

        /// <summary>
        /// Gets the description.
        /// </summary>
        /// <value>The description.</value>
        string Description { get; }

        /// <summary>
        /// Gets the author of the extension. Please provide complete information to get …
Run Code Online (Sandbox Code Playgroud)

.net code-contracts

9
推荐指数
1
解决办法
4516
查看次数

代码契约:我们是否必须在委托方法中冗余地指定Contract.Requires(...)语句?

我打算使用新的.NET 4 Code Contracts功能进行未来的开发.这让我想知道我们是否必须Contract.Requires(...)在一系列方法中冗余地指定等效语句.

我认为一个代码示例胜过千言万语:

    public bool CrushGodzilla(string weapon, int velocity)
    {
        Contract.Requires(weapon != null);

        // long code

        return false;
    }

    public bool CrushGodzilla(string weapon)
    {
        Contract.Requires(weapon != null);   // specify contract requirement here
                                             // as well???

        return this.CrushGodzilla(weapon, int.MaxValue);
    }
Run Code Online (Sandbox Code Playgroud)

对于运行时检查它并不重要,因为我们最终总是会遇到需求检查,如果失败我们会收到错误.

但是,当我们再次在第二次超载中没有指定合同要求时,它被认为是不好的做法吗?

此外,还将具有编译时检查的功能,并且还可能设计代码合同的时间检查.在Visual Studio 2010中,它似乎尚不适用于C#,但我认为有一些类似Spec#的语言已经可以使用.当我们编写代码来调用这样的方法时,这些引擎可能会给我们提示,而我们的参数目前可以或将会是null.

所以我想知道这些引擎是否总是会分析一个调用堆栈,直到找到一个目前不满意的合同方法?

此外,在这里我了解到的区别Contract.Requires(...)Contract.Assume(...).我想在这个问题的背景下还要考虑差异呢?

.net c# .net-4.0 code-contracts

9
推荐指数
1
解决办法
2165
查看次数

Contract.Exists如何增加价值?

我刚刚开始了解VS2010标配的代码契约库.我正在遇到的一件事是一些合同条款的真正含义.

例如,这两个陈述有何不同?

Contract.Requires(!mycollection.Any(a => a.ID == newID));
Contract.Requires(!Contract.Exists(mycollection, a => a.ID == newID));
Run Code Online (Sandbox Code Playgroud)

换句话说,Contract.Exists在实际应用中做了什么,对于使用我的函数的开发人员,还是对于静态代码分析系统?

c# code-contracts

9
推荐指数
1
解决办法
595
查看次数

为REST对象生成合同

我是REST的新手,听起来应该很简单.在.NET应用程序中,我可以创建对WCF服务的引用,并为我生成所有可用类型的合同.

现在我正在尝试在Windows Phone 7应用程序中使用REST服务.虽然我可以进行调用并获得正确的响应,但是有一种简单的方法来创建每个对象将被反序列化的类吗?

我正在使用RestSharp来管理我的呼叫.在我看到的一些例子中,用户已经创建了自己的类,并手动生成了xml.如果可能的话,我想避免这种情况.

非常感谢!

c# rest code-contracts windows-phone-7

9
推荐指数
1
解决办法
7182
查看次数

通用接口的嵌套合同

我可以为非泛型接口设置嵌套合同类型:

[ContractClass(typeof(Foo.FooContracts))]
public interface IFoo
{
    string Bar(object obj);
}
Run Code Online (Sandbox Code Playgroud)

但是当我尝试使用通用接口做同样的事情时,它会抱怨:

[ContractClass(typeof(Foo.FooContracts<>))]
public interface IFoo<T>
{
    string Bar(T obj);
}
Run Code Online (Sandbox Code Playgroud)

警告是:

合同类Foo+FooContracts`1和类型IFoo`1必须具有相同的声明类型(如果有).

如果我FooContracts离开Foo课堂,它会在没有警告的情况下编译.

  • 为什么通用接口存在这种限制?
  • 为什么非通用的限制不存在?

c# generics interface code-contracts

9
推荐指数
1
解决办法
530
查看次数

是否存在Resharper和Code Contracts都可以使用的常见PureAttribute?

我正在用C#编写ReSharper 8.0和VS2012 for .Net 4.0.

ReSharper包含一个属性:JetBrains.Annotations.PureAttribute.这用于提供检查"不使用纯方法的返回值".

代码约定包括一个属性:System.Diagnostics.Contracts.PureAttribute.代码合同检查使用它来确保调用不会产生可见的状态更改,因此不需要重新检查对象的状态.

目前,为了获得这两种工具的功能,需要使用每个属性的方法对方法进行注释.更糟糕的是,因为它们都共享相同的类型名称,所以您需要限定每个属性.

[Pure]
[Jetbrains.Annotations.Pure]
public bool isFinished() {
    ...
Run Code Online (Sandbox Code Playgroud)

为避免这种情况,应该有三种方法:

  1. 写一个由ReSharper和Contracts认可的占位符
  2. 让ReSharper识别Contracts属性
  3. 获取合同以识别ReSharper属性

这些都有可能吗?

c# resharper custom-attributes code-contracts

9
推荐指数
1
解决办法
1244
查看次数