Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 代码契约-ForAll-静态验证支持什么_C#_Static Analysis_Code Contracts - Fatal编程技术网

C# 代码契约-ForAll-静态验证支持什么

C# 代码契约-ForAll-静态验证支持什么,c#,static-analysis,code-contracts,C#,Static Analysis,Code Contracts,有大量信息表明,契约的静态检查。对于所有来说,支持的范围有限或没有 我做了很多实验,发现它可以与一起工作: Contract.ForAll(items,i=>i!=null) Contract.ForAll(items,p)其中p属于谓词类型 它不能与以下各项一起工作: 现场访问 财产访问权 方法组(我认为无论如何都在这里分配了委托) 实例方法调用 我的问题是: ForAll还可以使用哪些类型的代码 在Contract.ForAll(items,i=>i!=null)被证明从代码后面的

有大量信息表明,
契约的静态检查。对于所有
来说,支持的范围有限或没有

我做了很多实验,发现它可以与一起工作:

  • Contract.ForAll(items,i=>i!=null)
  • Contract.ForAll(items,p)
    其中
    p
    属于
    谓词类型
它不能
与以下各项一起工作:

  • 现场访问
  • 财产访问权
  • 方法组(我认为无论如何都在这里分配了委托)
  • 实例方法调用
我的问题是:

  • ForAll
    还可以使用哪些类型的代码
  • Contract.ForAll(items,i=>i!=null)被证明从代码后面的列表中获取一项时(即通过索引),该项不为null之后,代码是否会收缩
以下是完整的测试代码:

public sealed class Test
{
    public bool Field;
    public static Predicate<Test> Predicate;

    [Pure]
    public bool Property
    {
        get { return Field; }
    }    

    [Pure]
    public static bool Method(Test t)
    {
        return t.Field;
    }

    [Pure]
    public bool InstanceMethod()
    {
        return Field;
    }

    public static void Test1()
    {
        var items = new List<Test>();
        Contract.Assume(Contract.ForAll(items, i => i != null));
        Contract.Assert(Contract.ForAll(items, i => i != null)); // OK
    }

    public static void Test2()
    {
        var items = new List<Test>();
        Contract.Assume(Contract.ForAll(items, Predicate));
        Contract.Assert(Contract.ForAll(items, Predicate)); // OK
    }

    public static void Test3()
    {
        var items = new List<Test>();
        Contract.Assume(Contract.ForAll(items, i => i.Field));
        Contract.Assert(Contract.ForAll(items, i => i.Field)); // assert unproven
    }

    public static void Test4()
    {
        var items = new List<Test>();
        Contract.Assume(Contract.ForAll(items, i => i.Property));
        Contract.Assert(Contract.ForAll(items, i => i.Property)); // assert unproven
    }

    public static void Test5()
    {
        var items = new List<Test>();
        Contract.Assume(Contract.ForAll(items, Method));
        Contract.Assert(Contract.ForAll(items, Method)); // assert unproven
    }

    public static void Test6()
    {
        var items = new List<Test>();
        Contract.Assume(Contract.ForAll(items, i => i.InstanceMethod()));
        Contract.Assert(Contract.ForAll(items, i => i.InstanceMethod()));// assert unproven
    }
}
公共密封类测试
{
公共领域;
公共静态谓词;
[纯]
公共布尔财产
{
获取{返回字段;}
}    
[纯]
公共静态布尔法(试验t)
{
返回t.字段;
}
[纯]
公共布尔实例方法()
{
返回字段;
}
公共静态void Test1()
{
var items=新列表();
假设(Contract.ForAll(items,i=>i!=null));
Assert(Contract.ForAll(items,i=>i!=null));//确定
}
公共静态void Test2()
{
var items=新列表();
契约。假设(契约。所有(项目,谓词));
Contract.Assert(Contract.ForAll(items,Predicate));//确定
}
公共静态void Test3()
{
var items=新列表();
假设(Contract.ForAll(items,i=>i.Field));
Assert(Contract.ForAll(items,i=>i.Field));//Assert unproven
}
公共静态void Test4()
{
var items=新列表();
假设(Contract.ForAll(items,i=>i.Property));
Assert(Contract.ForAll(items,i=>i.Property));//Assert unproven
}
公共静态void Test5()
{
var items=新列表();
合同。假设(合同。所有(项目、方法));
Contract.Assert(Contract.ForAll(items,Method));//Assert unproven
}
公共静态void Test6()
{
var items=新列表();
Contract.aspect(Contract.ForAll(items,i=>i.InstanceMethod());
Contract.Assert(Contract.ForAll(items,i=>i.InstanceMethod());//Assert未经验证
}
}

通过反编译mscorelib.dll
System.Diagnostics.Contracts
我们可以轻松地看到Contract.ForAll是如何构建的:它需要集合和谓词

public static bool ForAll<T>(IEnumerable<T> collection, Predicate<T> predicate)
{
    if (collection == null)
    {
        throw new ArgumentNullException("collection");
    }
    if (predicate == null)
    {
        throw new ArgumentNullException("predicate");
    }
    foreach (T current in collection)
    {
        if (!predicate(current))
        {
            return false;
        }
    }
    return true;
}
publicstaticboolforall(IEnumerable集合,谓词)
{
if(集合==null)
{
抛出新的ArgumentNullException(“集合”);
}
if(谓词==null)
{
抛出新的ArgumentNullException(“谓词”);
}
foreach(集合中的T当前值)
{
if(!谓词(当前))
{
返回false;
}
}
返回true;
}
所以当你说
Contract.ForAll(items,i=>i.Field)
在这个例子中,
i=>i.Field
是谓词

然后,通过在所有测试方法中遵循您的示例,我们可以看到您为
Contract.ForAll
方法提供了一个空列表,该列表将返回true,因为它永远不会进入foreach块

更进一步说,如果您将项目添加到列表中
var items=newlist(){newtest()}
并再次运行测试,它将返回false作为
公共bool字段默认为false

总的来说,合同的目标是

确定集合中的所有元素是否存在于 作用


因此,我的结论是,这与Contarct无关。ForAll不能处理某些内容,而是集合中至少有一个元素返回false或为null

我无法找到更多的工作表达式,事实上,我发现即使是
Contract.ForAll(items,I=>I!=null)
也不能可靠地工作(但它知道,当后来在同一个函数中的foreach内部使用该项时,该项不是空的)。最后,我放弃了使用更复杂的ForAll contracts和static checker的可能性

相反,我设计了一种方法来控制哪些契约用于静态检查器,哪些契约用于运行时检查器。我在这里介绍了这种方法,希望它可能对对对原始问题感兴趣的人有用。好处是能够编写更复杂的契约,这些契约只能在运行时进行检查,并且只留下易于证明的契约用于静态检查器的RACT(并轻松保持低计数的警告)

为此,需要2个调试版本(如果您还没有),调试和调试+静态契约,调试生成有条件编译符号MYPROJECT\u Contracts\u RUNTIME定义。这样,它将接收所有
契约。
RtContract。
契约。其他生成只接收
契约。
契约

public static class RtContract
{
    [Pure] [ContractAbbreviator] [Conditional("MYPROJECT_CONTRACTS_RUNTIME")]
    public static void Requires(bool condition)
    {
        Contract.Requires(condition);
    }

    [Pure] [ContractAbbreviator] [Conditional("MYPROJECT_CONTRACTS_RUNTIME")]
    public static void Ensures(bool condition)
    {
        Contract.Ensures(condition);
    }

    [Pure] [Conditional("MYPROJECT_CONTRACTS_RUNTIME")]
    public static void Assume(bool condition)
    {
        Contract.Assume(condition);
    }
}

public class Usage
{
   void Test (int x)
   {
        Contract.Requires(x >= 0);  // for static and runtime
        RtContract.Requires(x.IsFibonacci());  // for runtime only
   }
}

感谢您的努力,但我的问题是关于代码契约引擎进行静态分析的能力。这与ForAll函数的代码中实现的运行时特征无关。