2010-01-27 9 views
33

me gustaría especificar un contrato para este interfaz genérica, utilizando Code Contracts:Contratos de código: ¿Cómo proporciono una clase contractual para una interfaz genérica?

interface IRandomWriteAccessible<T> 
{ 
    T this[uint index] { set; } 
    uint Length { get; } 
} 

La documentación dice que use el atributo ContractClass cuando se especifica un contrato para una interfaz. Sin embargo, el compilador se quejará de esto:

[ContractClass(typeof(IRandomWriteAccessibleContract<T>))] 
//    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^  <-- compiler error 
interface IRandomWriteAccessible<T> { … } 

[ContractClassFor(typeof(IRandomWriteAccessible<T>))] 
//    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   <-- compiler error 
sealed class IRandomWriteAccessibleContract<T> : IRandomWriteAccessible<T> { … } 

Parece que los parámetros de tipo no se pueden usar con atributos.

Cómo do Escribo un contrato para mi interfaz genérica? ¿O esto no es posible con los Contratos de Código?

+2

no he verificado esto, pero quitar el ' T' de su uso de atributos de la siguiente manera: '[ContractClass (typeof (IRandomWriteAccessibleContract <>))] ' –

+0

@ Steve Guidi: OMG, este cambio realmente hace feliz al compilador. Todavía no he comprobado si realmente funciona como se esperaba. Te informaré tan pronto como sepa más. Gracias hasta ahora. – stakx

+1

@ Steve Guidi: Tu sugerencia funciona. Si vuelve a publicarlo como respuesta, me complacería marcarlo como la respuesta aceptada. ¡Gracias por tu ayuda! – stakx

Respuesta

45

Como se ha mencionado por otros comentarios en esta pregunta, debe quitar el identificador de tipo genérico de su uso atributo, ya que no se puede resolver en tiempo de compilación:

[ContractClass(typeof(IRandomWriteAccessibleContract<>))] 
+5

Lo busqué en la especificación de lenguaje C# por curiosidad: los capítulos relevantes son _14.5.11 (operador typeof) _ y _25.5 (genéricos: tipos construidos) _, si alguien más está interesado. – stakx

+15

Además, si la clase genérica es typeof() 'ing toma más de un parámetro, debe usar comas; por ejemplo, typeof (YourType <,>), donde YourType toma dos parámetros de tipo. –

1

Buena pregunta, pero puede ver las razones técnicas detrás de esta limitación, ¿verdad?

La razón por la que no puede especificar el ContractClass es porque Blah<T> no es una clase.

Si puede hacer una interfaz para una clase concreta especificando un valor para T, aunque estoy seguro de que no es óptimo.

+0

Bueno, sí, supongo que esto tiene sentido (desde el punto de vista del compilador). Todavía espero que haya algún tipo de solución genérica, porque no tengo ganas de especificar el mismo contrato para todos los tipos posibles 'T' ... – stakx

+0

¿Funcionó la sugerencia de @Steve Guidi? –

+0

@ John: ¡Sí, funcionó! – stakx

Cuestiones relacionadas