Microsoft 开发人员网络 > 论坛主页 > Code Contracts > How do I put a contract on a generic interface?
提出问题提出问题
 

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

  • 2009年2月26日 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

答案

  • 2009年2月26日 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

全部回复

  • 2009年2月26日 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
  • 2009年2月27日 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]
  • 2009年2月27日 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