Code contracte des avertissements lors de la mise en œuvre de la mise en œuvre de la collection de soutien

StackOverflow https://stackoverflow.com/questions/5457303

Question

J'ai ce 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; }
    }
}

Je reçois ces avertissements:

  • Ajouter: CodeContracts: assure non prouvé: this.Count >= Contract.OldValue(this.Count)
  • Clear: CodeContracts: Assure non prouvé: this.Count == 0
  • Contient: CodeContracts: assure non prouvé: !Contract.Result<bool>() || this.Count > 0
  • CopyTo: CodeContracts: nécessite non prouvé: arrayIndex + this.Count <= array.Length

Comment puis-je les réparer? Existe-t-il un moyen de simplement les supprimer?

Était-ce utile?

La solution

Je ne sais pas si je suis la question mais j'ai essayé le code suivant (implémenté toutes les interfaces requises) et myCollection myCollection = new MyCollection {"test"}; fonctionnait bien. Si vous avez encore des problèmes, essayez d'expliquer un peu plus ce que vous avez fait.

ÉDITER:Outre ma réponse à la question, je voudrais faire la note suivante pour ceux qui font les premiers étapes avec les contrats de code.

Pour obtenir les contrats de code pour afficher les avertissements, la vérification statique doit être active (Propriétés du projet -> Contrats de code -> Effectuer une vérification statique du contrat) qui n'est disponible que si un contrat de code Premium (non standard) est installé sur Visual Studio 2010 Premium ou sur 2008 Système d'équipe.

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:

Il y a du travail, choisissez-en un qui vous convient le mieux:

  1. Ajouter un contrat manquant.assets comme vu sur l'échantillon de code ci-dessus;
  2. Au lieu d'implémenter ICOllection inhérente à la collection;
  3. Utilisation StringCollection

Les solutions ont été tirées du poste de forum DevLabs: Problèmes avec le vérificateur statique et l'emballage autour de la liste générique.

EDIT 3 (par AllRamest):

  1. Ajoutée Contract.Ensures(Contract.Result<int>() == backEndCollection.Count); à la propriété Count dont Komet a fait un tour de Komet.
  2. Ajoutée Contract.Assume(arrayIndex + Count <= array.Length); à la méthode Copyto.
  3. Supprimé Contract.Assert(_inner.Count == 0); de la méthode claire.

Autres conseils

D'après ce que je vois à partir de plusieurs liens, vous devez ajouter cette ligne à la propriété Count:

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

Sources :

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

http://social.msdn.microsoft.com/forums/en-us/codeconstral/thread/acb3e1d8-8239-4b66-b842-85a1a9509d1e/

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top