Je suis enfin de rattraper leur retard avec tout le nouveau qui a été ajouté à la .NET 3.5/4.0 Cadres. Depuis quelques jours, j'ai pu travailler avec CodeContracts et je suis vraiment tenté de les aimer. Je suis curieux de savoir ce que les autres pensent de la mise en œuvre de CodeContracts en C#? Plus précisément, comment sont les gens à organiser des choses comme le Contrat de classes pour les interfaces, contrat de méthodes pour le Contrat Invariants etc?
J'aime la validation des contrats de fournir, à première vue, ils ressemblent beaucoup. Avec quelques simples lignes je peux obtenir quelques belles construire la vérification avant même d'exécuter mon code. Malheureusement, je vais avoir du mal à passer par-dessus le sentiment que la façon dont les contrats de code sont de mettre en œuvre en C#, ils sont d'encombrer mon code plus que ce qu'ils documentent les contrats. Et pour profiter pleinement de contrats, je suis jonchent mon code avec des hypothèses et affirme etc (je sais certains vont dire, c'est une bonne chose); mais comme certains de mes exemples ci-dessous montrent, il s'avère une simple ligne de 4 ou 5 lignes, et n'a pas vraiment d'ajouter une valeur suffisante à mon avis, par rapport à d'autres approches (c'est à dire, affirme, exceptions...).
Actuellement, mes plus grandes frustrations sont:
Des Contrats D'Interface:
[ContractClass(typeof(IInterfaceContract))]
public interface IInterface
{
Object Method(Object arg);
}
[ContractClassFor(typeof(IInterface))]
internal abstract class IInterfaceContract
{
private IInterfaceContract() { }
Object IInterface.Method(Object arg)
{
Contract.Requires(arg != null);
Contract.Ensures(Contract.Result<Object>() != null);
return default(Object);
}
}
Cela se sent comme un cludge pour moi, je souhaite qu'il y avait une manière plus propre aux exigences en matière de documents, soit par l'intermédiaire d'attributs ou de certaines formes de bâti de support de la langue. Le fait que je dois implémenter une classe abstraite qui implémente mon interface, juste pour que je puisse spécifier le contrat semble fastidieux, au mieux.
Augmentation Du Code:
typeof(Action<>).MakeGenericType(typeof(Object);
Nécessite plusieurs hypothèses, juste pour vérifier l'information qui est facilement disponible. J'apprécie le fait que tous l'analyseur sait, c'est qu'il fonctionne sur le Type et doit donc travailler sur ce peu de connaissances, mais elle continue de me frustre qu'une seule ligne de code m'oblige à ré-écrire comme
var genericAction = typeof(Action<>);
Contract.Assume(genericAction.IsGenericType);
Contract.Assume(genericAction.GetGenericArguments().Length == 1);
genericAction.MakeGenericType(typeof(Object));
Juste pour garder les choses documentées (oui, je sais que je peux utiliser ContractVerificationAttribute de désactiver cette fonction pour une méthode de classe, etc, ou SuppressMessageAttribbute à la cible de messages spécifiques, mais qui semble à l'encontre du but que votre code deviendrait rapidement jonché de suppressions, etc.
En outre, en prenant un cas comme
public class MyClass
: IInterface
{
private readonly Object _obj;
public Object Property
{
get
{
Contract.Ensures(Contract.Result<Object>() != null);
return _obj;
}
}
public MyClass(Object obj)
{
Contract.Requires(obj != null);
_obj = obj;
}
}
obj est nécessaire pour ne pas être nulle, et est fixé à un champ en lecture seule qui ne peut pas être changé, mais je suis encore obligé d'ajouter un "balisage" méthode de ma classe, de sorte que mon exigence de la propriété de ne pas retourner la valeur null peut être prouvé:
[ContractInvariantMethod]
private void ObjectInvariant()
{
Contract.Invariant(_obj != null);
}
Il n'y est plus, mais j'ai pensé que j'ai probablement déclamée assez, et je voudrais vraiment l'apprécier du point de vue de gens beaucoup plus intelligents que moi pour m'aider à "comme" des Contrats de Code et de faire de ce sentiment de l'encombrement de code en aller. Aucune indication sur la façon de mieux structurer le code, la solution de contournement wonkiness questions etc serait grandement apprécié.
Merci!