Microsoft Developer Network > Página Inicial dos Fóruns > Code Contracts > How do I put a contract on a generic interface?
Fazer uma PerguntaFazer uma Pergunta
 

RespondidoHow do I put a contract on a generic interface?

  • quinta-feira, 26 de fevereiro de 2009 11:33OpinionatedGeek Medalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuário
     Contém Código
    Say I have the following interface:

    public interface IParser<T>
    {
        T Parse (
    string toParse);
    }

    How do I specify the attributes for the contract class?

    My initial thought was:

    [ContractClass (typeof (IParserContract<T>))]
    public interface IParser<T>
    {
        T Parse (
    string toParse);
    }

    and

    [ContractClassFor (typeof (IParser<T>))]
    public class IParserContract<T>
    {
        ...
    }

    But that won't work, because you can't use the generic T argument in the attributes.  And leaving the generic argument out won't work, because that doesn't specify the right interface/type.

    So, am I missing the proper way of doing this, or is this a limitation?

    Cheers,

        Geoff

Respostas

  • quinta-feira, 26 de fevereiro de 2009 15:26Manuel FahndrichMSFT, ProprietárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuário
     RespondidoContém Código
    Excellent question and we probably should put this into the documentation. For generic interface contracts, the typeof has to refer to the non-instantiated generic type. This is a little known C# feature. It looks as follows:

    [ContractClass (typeof (IParserContract<>))]  
    public interface IParser<T>  
    {  
        T Parse (string toParse);  
    }  
     
    [ContractClassFor (typeof (IParser<>))]  
    public class IParserContract<T>  
    {  
        ...  
    }  
     
     

    Note the empty instantiation brackets IParserContract<> and IParser<>.

    -MaF

Todas as Respostas

  • quinta-feira, 26 de fevereiro de 2009 15:26Manuel FahndrichMSFT, ProprietárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuário
     RespondidoContém Código
    Excellent question and we probably should put this into the documentation. For generic interface contracts, the typeof has to refer to the non-instantiated generic type. This is a little known C# feature. It looks as follows:

    [ContractClass (typeof (IParserContract<>))]  
    public interface IParser<T>  
    {  
        T Parse (string toParse);  
    }  
     
    [ContractClassFor (typeof (IParser<>))]  
    public class IParserContract<T>  
    {  
        ...  
    }  
     
     

    Note the empty instantiation brackets IParserContract<> and IParser<>.

    -MaF
  • sexta-feira, 27 de fevereiro de 2009 0:48Keith Farmer Medalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuário
     

    For multi-parameter generics, as you might imagine, you can use IFoo<,,,,> -- just drop the generic identifiers, leaving the commas, and you're good to go.

    This is also useful in instantiating generic types via reflection.  typeof(List<>) returns a valid type awaiting parameterization.


    Keith J. Farmer [Idea Entity]
  • sexta-feira, 27 de fevereiro de 2009 10:03OpinionatedGeek Medalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuário
     
    Manuel Fahndrich said:

    For generic interface contracts, the typeof has to refer to the non-instantiated generic type. This is a little known C# feature.

    That's excellent - many thanks.  And I thought I knew most of the little-known C# features...!

    Cheers,

    Geoff