MSDN > 論壇首頁 > Code Contracts > How do I put a contract on a generic interface?
發問發問
 

已答覆How do I put a contract on a generic interface?

  • Thursday, 26 February, 2009 11:33OpinionatedGeek 使用者勳章使用者勳章使用者勳章使用者勳章使用者勳章
     包含代碼
    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

解答

  • Thursday, 26 February, 2009 15:26Manuel FahndrichMSFT, 擁有者使用者勳章使用者勳章使用者勳章使用者勳章使用者勳章
     已答覆包含代碼
    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

所有回覆

  • Thursday, 26 February, 2009 15:26Manuel FahndrichMSFT, 擁有者使用者勳章使用者勳章使用者勳章使用者勳章使用者勳章
     已答覆包含代碼
    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
  • Friday, 27 February, 2009 0:48Keith Farmer 使用者勳章使用者勳章使用者勳章使用者勳章使用者勳章
     

    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]
  • Friday, 27 February, 2009 10:03OpinionatedGeek 使用者勳章使用者勳章使用者勳章使用者勳章使用者勳章
     
    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