Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/319.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# 代码契约:IEnumerable.Min上的静态检查失败_C#_Code Contracts - Fatal编程技术网

C# 代码契约:IEnumerable.Min上的静态检查失败

C# 代码契约:IEnumerable.Min上的静态检查失败,c#,code-contracts,C#,Code Contracts,我在下面包含代码契约的代码中得到一些警告 public static int Min(IEnumerable<int> set) { Contract.Requires(set != null); Contract.Requires(set.Any()); Contract.Ensures(Contract.ForAll(set, x => x >= Contract.Result<int>())); int min = s

我在下面包含代码契约的代码中得到一些警告

public static int Min(IEnumerable<int> set)
{
    Contract.Requires(set != null);
    Contract.Requires(set.Any());

    Contract.Ensures(Contract.ForAll(set, x => x >= Contract.Result<int>()));

    int min = set.Min();

    return min;
}

static void Main(string[] args)
{
    Console.WriteLine(Min(new int[] {3,4,5}));
    Console.WriteLine(Min(new int[] {})); // should fail
}
publicstaticintmin(IEnumerable集合)
{
Contract.Requires(set!=null);
Contract.Requires(set.Any());
Contract.survey(Contract.ForAll(set,x=>x>=Contract.Result());
int min=set.min();
返回最小值;
}
静态void Main(字符串[]参数)
{
Console.WriteLine(Min(新的int[]{3,4,5}));
WriteLine(Min(new int[]{}));//应该失败
}
我收到以下警告:

Requires unproven: set.Any() on Min(new int[] {3,4,5})

Ensures unproven: Contract.ForAll(set, x => x > Contract.Result<int>())
    public static int Min(List<int> set)
    {
        Contract.Requires(set != null);
        Contract.Requires(set.Count>0);


        Contract.Ensures(Contract.ForAll(set, x => x >= Contract.Result<int>()));

        int min = set.Min();

        return min;
    }

    static void Main(string[] args)
    {

        Console.WriteLine(Min(new List<int> { })); // should fail
        Console.WriteLine(Min(new List<int> { 3, 4, 5 }));
        Console.ReadKey();
    }
要求在Min(new int[]{3,4,5})上使用未经验证的:set.Any()
确保未经验证:Contract.ForAll(set,x=>x>Contract.Result())
两个问题:

  • 我的后置条件声明x>=Contract.Result(),但“确保未经验证”警告声明x>Contract.Result()。(Greather或equal vs.Greather)这怎么可能发生

  • 为什么不能在上面的语句中证明set.Any()


  • 提前谢谢。

    首先,
    确保
    子句对所有的
    IEnumerable
    无效。您可以编写一个
    IEnumerable
    ,第一次枚举时返回一个序列(例如
    1、2、3
    ),第二次返回另一个列表(例如
    0
    )。它是一个具有任意实现的接口

    IEnumerable
    通常有很多(潜在生成的)东西在幕后进行。我不认为CC能看穿这一点,即使具体的运行时类型不知何故是已知的

    CC甚至能够对
    IEnumerable
    进行启发式推理吗?这对我来说是新鲜事。它必须假设一个序列在多次枚举时不会改变(在数据库查询的情况下这是非常错误的)


    让我指出,作为主观方面的注意,我发现CC检查器太过有限,没有任何用处。它会给证明有趣的属性带来极大的麻烦。它不能很好地处理抽象。

    这个
    子句确保了
    子句并非对所有
    IEnumerable
    都有效。您可以编写一个
    IEnumerable
    ,第一次枚举时返回一个序列(例如
    1、2、3
    ),第二次返回另一个列表(例如
    0
    )。它是一个具有任意实现的接口

    IEnumerable
    通常有很多(潜在生成的)东西在幕后进行。我不认为CC能看穿这一点,即使具体的运行时类型不知何故是已知的

    CC甚至能够对
    IEnumerable
    进行启发式推理吗?这对我来说是新鲜事。它必须假设一个序列在多次枚举时不会改变(在数据库查询的情况下这是非常错误的)


    让我指出,作为主观方面的注意,我发现CC检查器太过有限,没有任何用处。它会给证明有趣的属性带来极大的麻烦。它不能很好地处理抽象。

    静态代码检查器无法确定该集合包含任何数据。如果您仔细想想,检查器不知道各种方法和属性的作用,除非一些契约是在方法本身内部定义的

    在您的例子中,检查程序不知道扩展方法Any()或Min()的结果,因此无法验证任何要求和保证

    通过更改参数的类型,您可以得到较少的警告,但最终代码检查器仍然无法确保您的代码能够满足Min(…)的要求

    如果将类型更改为int[]或List,某些警告可能会消失。以下代码不返回任何警告:

    Requires unproven: set.Any() on Min(new int[] {3,4,5})
    
    Ensures unproven: Contract.ForAll(set, x => x > Contract.Result<int>())
    
        public static int Min(List<int> set)
        {
            Contract.Requires(set != null);
            Contract.Requires(set.Count>0);
    
    
            Contract.Ensures(Contract.ForAll(set, x => x >= Contract.Result<int>()));
    
            int min = set.Min();
    
            return min;
        }
    
        static void Main(string[] args)
        {
    
            Console.WriteLine(Min(new List<int> { })); // should fail
            Console.WriteLine(Min(new List<int> { 3, 4, 5 }));
            Console.ReadKey();
        }
    
    public static int Min(列表集)
    {
    Contract.Requires(set!=null);
    合同要求(集合计数>0);
    Contract.survey(Contract.ForAll(set,x=>x>=Contract.Result());
    int min=set.min();
    返回最小值;
    }
    静态void Main(字符串[]参数)
    {
    WriteLine(Min(新列表{}));//应该失败
    WriteLine(Min(新列表{3,4,5}));
    Console.ReadKey();
    }
    
    当然,如果您运行此代码,它将失败并出现异常,因此代码检查器可能足够聪明,能够检测到这一点

    如果您保持原来的顺序,您仍然会收到警告:

            Console.WriteLine(Min(new List<int> { 3, 4, 5 }));
            Console.WriteLine(Min(new List<int> { })); // should fail
    
    Console.WriteLine(Min(新列表{3,4,5}));
    Console.WriteLine(Min(新列表{}));//应该失败
    

    在这两种情况下,您也会得到一些疯狂的建议,比如在Main()中添加Contract.surveures(false)。

    静态代码检查器无法确定该集合包含任何数据。如果您仔细想想,检查器不知道各种方法和属性的作用,除非一些契约是在方法本身内部定义的

    在您的例子中,检查程序不知道扩展方法Any()或Min()的结果,因此无法验证任何要求和保证

    通过更改参数的类型,您可以得到较少的警告,但最终代码检查器仍然无法确保您的代码能够满足Min(…)的要求

    如果将类型更改为int[]或List,某些警告可能会消失。以下代码不返回任何警告:

    Requires unproven: set.Any() on Min(new int[] {3,4,5})
    
    Ensures unproven: Contract.ForAll(set, x => x > Contract.Result<int>())
    
        public static int Min(List<int> set)
        {
            Contract.Requires(set != null);
            Contract.Requires(set.Count>0);
    
    
            Contract.Ensures(Contract.ForAll(set, x => x >= Contract.Result<int>()));
    
            int min = set.Min();
    
            return min;
        }
    
        static void Main(string[] args)
        {
    
            Console.WriteLine(Min(new List<int> { })); // should fail
            Console.WriteLine(Min(new List<int> { 3, 4, 5 }));
            Console.ReadKey();
        }
    
    public static int Min(列表集)
    {
    Contract.Requires(set!=null);
    合同要求(集合计数>0);
    Contract.survey(Contract.ForAll(set,x=>x>=Contract.Result());
    int min=set.min();
    返回最小值;
    }
    静态void Main(字符串[]参数)
    {
    WriteLine(Min(新列表{}));//应该失败
    WriteLine(Min(新列表{3,4,5}));
    Console.ReadKey();
    }
    
    当然,如果您运行此代码,它将失败并出现异常,因此代码检查器可能足够聪明,能够检测到这一点

    如果您保持原来的顺序,您仍然会收到警告:<