使用支持集合实现 ICollection 时代码契约警告

发布于 2024-10-27 09:47:19 字数 1690 浏览 1 评论 0原文

我有这个代码:

public class MyCollection : ICollection<string>
{
    private readonly ICollection<string> _inner = new Collection<string>();

    public void Add(string item)
    {
        _inner.Add(item);
    } // <-- CodeContracts: ensures unproven: this.Count >= Contract.OldValue(this.Count)

    public void Clear()
    {
        _inner.Clear();
    } // <-- CodeContracts: ensures unproven: this.Count == 0

    public bool Contains(string item)
    {
        return _inner.Contains(item); // <-- CodeContracts: ensures unproven: !Contract.Result<bool>() || this.Count > 0
    }

    public void CopyTo(string[] array, int arrayIndex)
    {
        _inner.CopyTo(array, arrayIndex); // <-- CodeContracts: requires unproven: arrayIndex + this.Count  <= array.Length
    }

    public IEnumerator<string> GetEnumerator()
    {
        return _inner.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    public bool Remove(string item)
    {
        return _inner.Remove(item);
    }

    public int Count
    {
        get { return _inner.Count; }
    }

    public bool IsReadOnly
    {
        get { return _inner.IsReadOnly; }
    }
}

我收到这些警告:

  • 添加:CodeContracts:确保未经证实:this.Count&gt;= Contract.OldValue(this.Count)
  • 清除:CodeContracts:确保未经证实:this.Count == 0
  • 包含:CodeContracts:确保未经验证:!Contract.Result() || this.Count > 0
  • CopyTo:CodeContracts:需要未经验证:arrayIndex + this.Count <= array.Length

如何修复这些问题?有什么办法可以抑制这些吗?

I've got this code:

public class MyCollection : ICollection<string>
{
    private readonly ICollection<string> _inner = new Collection<string>();

    public void Add(string item)
    {
        _inner.Add(item);
    } // <-- CodeContracts: ensures unproven: this.Count >= Contract.OldValue(this.Count)

    public void Clear()
    {
        _inner.Clear();
    } // <-- CodeContracts: ensures unproven: this.Count == 0

    public bool Contains(string item)
    {
        return _inner.Contains(item); // <-- CodeContracts: ensures unproven: !Contract.Result<bool>() || this.Count > 0
    }

    public void CopyTo(string[] array, int arrayIndex)
    {
        _inner.CopyTo(array, arrayIndex); // <-- CodeContracts: requires unproven: arrayIndex + this.Count  <= array.Length
    }

    public IEnumerator<string> GetEnumerator()
    {
        return _inner.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    public bool Remove(string item)
    {
        return _inner.Remove(item);
    }

    public int Count
    {
        get { return _inner.Count; }
    }

    public bool IsReadOnly
    {
        get { return _inner.IsReadOnly; }
    }
}

I get these warnings:

  • Add: CodeContracts: ensures unproven: this.Count >= Contract.OldValue(this.Count)
  • Clear: CodeContracts: ensures unproven: this.Count == 0
  • Contains: CodeContracts: ensures unproven: !Contract.Result<bool>() || this.Count > 0
  • CopyTo: CodeContracts: requires unproven: arrayIndex + this.Count <= array.Length

How do I fix these? Is there some way to just suppress these?

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

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

发布评论

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

评论(2

闻呓 2024-11-03 09:47:19

不确定我是否遵循这个问题,但我尝试了以下代码(实现了所有必需的接口)和 MyCollection myCollection = new MyCollection {"test"};工作得很好。如果您仍然遇到问题,请尝试进一步解释您所做的事情。

编辑:
除了我对这个问题的回答之外,我还想为那些迈出代码契约第一步的人做以下说明。

要使代码合同显示警告,静态检查必须处于活动状态(项目属性 -> 代码合同 -> 执行静态合同检查),只有在 Visual Studio 2010 Premium 上安装代码合同高级(非标准)版本时才可用。 2008年团队系统。

public class MyCollection : ICollection<string>
{
    //using System;
    //using System.Collections;
    //using System.Collections.Generic;
    //using System.Collections.ObjectModel;
    //using System.Diagnostics.Contracts;

    private readonly ICollection<string> _inner = new Collection<string>();

    #region ICollection<string> Members

    public void Add(string item)
    {
        int oldCount = Count;
        _inner.Add(item);

        Contract.Assume(Count >= oldCount);
    }

    public void Clear()
    {
        _inner.Clear();

        Contract.Assume(Count == 0);
    }

    public bool Contains(string item)
    {
        bool result = _inner.Contains(item);
        // without the following assumption:
        // "ensures unproven: !Contract.Result<bool>() || this.Count > 0"
        Contract.Assume(!result || (Count > 0));

        return result;
    }

    public void CopyTo(string[] array, int arrayIndex)
    {
        Contract.Assume(arrayIndex + Count <= array.Length);
        _inner.CopyTo(array, arrayIndex);
    }

    public bool Remove(string item)
    {
        return _inner.Remove(item);
    }

    public int Count
    {
        get
        {
            Contract.Ensures(Contract.Result<int>() == _inner.Count);
            return _inner.Count;
        }
    }

    public bool IsReadOnly
    {
        get { return _inner.IsReadOnly; }
    }

    public IEnumerator<string> GetEnumerator()
    {
        return _inner.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    #endregion
}

编辑2:

有一些解决方法,选择最适合您的一个:

  1. 添加缺少的Contract.Asserts,如上面的代码示例所示;
  2. 而不是实现 Collection 固有的 ICollection;
  3. 使用 StringCollection

解决方案取自 DevLabs 论坛帖子:静态检查器和包装器的问题通用列表

编辑3(由Allrameest):

  1. Contract.Ensures(Contract.Result() == backEndCollection.Count);添加到KoMet提示的Count属性中。
  2. Contract.Assume(arrayIndex + Count <= array.Length); 添加到 CopyTo 方法。
  3. 从 Clear 方法中删除了 Contract.Assert(_inner.Count == 0);

Not sure if I follow the question but I tried the following code (implemented all required interfaces) and MyCollection myCollection = new MyCollection {"test"}; worked fine. If you are still having trouble then try to explain a little bit more what you did.

EDIT:
Apart from my answer to the question I would like to make the following note for those who are making the first steps with Code Contracts.

To get the Code Contracts to show warnings Static Checking must be active (Project properties -> Code Contracts -> Perform Static Contract Checking) which is only available if Code Contract premium (not standard) edition is installed on Visual Studio 2010 Premium or on 2008 Team System.

public class MyCollection : ICollection<string>
{
    //using System;
    //using System.Collections;
    //using System.Collections.Generic;
    //using System.Collections.ObjectModel;
    //using System.Diagnostics.Contracts;

    private readonly ICollection<string> _inner = new Collection<string>();

    #region ICollection<string> Members

    public void Add(string item)
    {
        int oldCount = Count;
        _inner.Add(item);

        Contract.Assume(Count >= oldCount);
    }

    public void Clear()
    {
        _inner.Clear();

        Contract.Assume(Count == 0);
    }

    public bool Contains(string item)
    {
        bool result = _inner.Contains(item);
        // without the following assumption:
        // "ensures unproven: !Contract.Result<bool>() || this.Count > 0"
        Contract.Assume(!result || (Count > 0));

        return result;
    }

    public void CopyTo(string[] array, int arrayIndex)
    {
        Contract.Assume(arrayIndex + Count <= array.Length);
        _inner.CopyTo(array, arrayIndex);
    }

    public bool Remove(string item)
    {
        return _inner.Remove(item);
    }

    public int Count
    {
        get
        {
            Contract.Ensures(Contract.Result<int>() == _inner.Count);
            return _inner.Count;
        }
    }

    public bool IsReadOnly
    {
        get { return _inner.IsReadOnly; }
    }

    public IEnumerator<string> GetEnumerator()
    {
        return _inner.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    #endregion
}

EDIT 2:

There are some work around, choose one which best suits you:

  1. Add missing Contract.Asserts as seen on above code sample;
  2. Instead of implementing ICollection inherent from Collection;
  3. Use StringCollection

The solutions were taken from DevLabs forum post: Problems with static checker and wrapper around generic list.

EDIT 3 (by Allrameest):

  1. Added Contract.Ensures(Contract.Result<int>() == backEndCollection.Count); to the Count property which KoMet tipped about.
  2. Added Contract.Assume(arrayIndex + Count <= array.Length); to the CopyTo method.
  3. Removed Contract.Assert(_inner.Count == 0); from the Clear method.
三岁铭 2024-11-03 09:47:19

从我从多个链接中看到的情况来看,您需要将此行添加到 Count 属性:

Contract.Ensures(Contract.Result<int>() == backEndCollection.Count);

来源:

http://social.msdn.microsoft.com/Forums/en/codecontracts/thread/cadd0c05-144e-4b99-b7c3-4869c46a95a2

http://social.msdn.microsoft.com /Forums/zh-CN/codecontracts/thread/acb3e1d8-8239-4b66-b842-85a1a9509d1e/

From what I see from multiple links, you need to add this line to the Count property:

Contract.Ensures(Contract.Result<int>() == backEndCollection.Count);

Sources :

http://social.msdn.microsoft.com/Forums/en/codecontracts/thread/cadd0c05-144e-4b99-b7c3-4869c46a95a2

http://social.msdn.microsoft.com/Forums/en-US/codecontracts/thread/acb3e1d8-8239-4b66-b842-85a1a9509d1e/

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