Estoy tratando de demostrar invariantes en Contratos de código, y pensé que daría un ejemplo de una lista ordenada de cadenas. Mantiene una matriz internamente, con espacio adicional para adiciones, etc., al igual que List<T>
, básicamente. Cuando se tiene que añadir un elemento, se inserta en la matriz, etc. pensé que tenía tres invariantes:¿Cuán libre puedo estar en el código en un objeto invariante?
- El recuento debe ser sensible: no negativos y como máximo tan grande como el tamaño del búfer
- Todo en la parte no utilizada de la memoria intermedia debe ser nula
- Cada elemento de la parte utilizada de la memoria intermedia debe ser al menos tan "grande" como el tema antes de que
Ahora, he tratado de implementar eso de esta manera:
[ContractInvariantMethod]
private void ObjectInvariant()
{
Contract.Invariant(count >= 0 && count <= buffer.Length);
for (int i = count; i < buffer.Length; i++)
{
Contract.Invariant(buffer[i] == null);
}
for (int i = 1; i < count; i++)
{
Contract.Invariant(string.Compare(buffer[i], buffer[i - 1]) >= 0);
}
}
Desafortunadamente, ccrewrite
está estropeando los bucles.
La documentación del usuario dice que el método debe ser simplemente una serie de llamadas al Contract.Invariant
. ¿Realmente tengo que volver a escribir el código como algo así?
Contract.Invariant(count >= 0 && count <= buffer.Length);
Contract.Invariant(Contract.ForAll
(count, buffer.Length, i => buffer[i] == null));
Contract.Invariant(Contract.ForAll
(1, count, i => string.Compare(buffer[i], buffer[i - 1]) >= 0));
Eso es algo feo, aunque funciona. (Es mucho mejor que mi intento anterior, piénselo).
¿Mis expectativas son irrazonables? ¿Son mis invariantes irrazonables?
(también pidió como question in the Code Contracts forum. Voy a añadir respuestas pertinentes aquí mismo.)
Al parecer, no se puede ser tan libre como el bucle se desenrolla./rimshot –
Lo extraño es que el * primer * bucle está bien ... pero el segundo no. Puede ser un error en la escritura, por supuesto. –
(sospecho que sea la captura de todo el código antes de la llamada a Contract.Invariant ...) –