If you are using an external library (e.g. mscorlib.dll), it does not seem feasible to use attributes there for specifying code annotations.
In this case, you can use External Annotations that allow you to complement the already compiled entities with attributes used by ReSharper’s code analysis engine. External Annotations let you 'cheat' the engine, by making it see the attributes (for methods, parameters and other declarations) which were not declared at the time the library was compiled.
Exactly this approach was used to annotate a huge amount of symbols in the .NET Framework Class Library, as well as NUnit Framework.
Annotations for members of a class library increase the efficiency of code analysis that ReSharper carries out. For example, StringFormatMethodAttribute is used to annotate String.Format-like methods the way that ReSharper checks the number of provided arguments against the structure of the format string and warns the user if a necessary argument is missing (see Defining Custom String Formatting Methods for guidelines).
The XML files that implement External Annotations have a structure similar to XmlDoc. For example, for the method XmlReader.Create(Stream input) from the assembly System.Xml of .NET Framework 4.0, NotNull contracts are defined as follows:
<assembly name=”System.Xml, Version=188.8.131.52″> <!—The attribute name contains the assembly name. If you don’t specify the version, this file’s attributes will be applied to all versions of the assemblies of that name –> <member name=”M:System.Xml.XmlReader.Create(System.IO.Stream)”> <!—This shows the name of the member whose attributes are complemented; the notation is the same as XmlDoc –> <attribute ctor=”M:JetBrains.Annotations.NotNullAttribute.#ctor” /> <!—attribute constructor names are also specified using XmlDoc notation –> <parameter name=”input”> <attribute ctor=”M:JetBrains.Annotations.NotNullAttribute.#ctor” /> </parameter> </member> </assembly>
You can use this approach to specify contracts for any compiled library.
To make sure ReSharper recognizes the XML file with External Annotations, you should store it either as [ReSharper install directory]\Bin\ExternalAnnotations\[Assembly name].xml or as [ReSharper install directory]\Bin\ExternalAnnotations\[Assembly name]\[Any name].xml, where [Assembly name] is the assembly name without the version. If you use the latter kind of location structure, you will be able to specify multiple sets of contracts for the same assembly. This may be useful if you need to use different contracts for different assembly versions.
You will notice that in this directory you can find definitions of contracts for standard libraries. These contracts are obtained based on source code analysis as well as Microsoft Contracts. The contracts obtained using the former technique are stored in files of the type *.Generated.xml, while those obtained using the latter technique are stored in files of the type *.Contracts.xml.
To see what external annotations are applied to a particular library symbol, use
Quick Documentation. Just press
Ctrl+Q over the symbol in question and study its attributes: