Ever since I was in the C++ world, I have been enamored with code analysis tools; I used to live by PC-Lint. So since I started using C# a few years ago code analysis was something that I wanted to integrate into my C# coding practice as well. The first tool that I started using was FxCop, a tool that analyzes managed code assemblies and produces similar useful results. Since I have been doing lots of Silverlight work lately, I was excited to see that FxCop is now part of Visual Studio 2008 - in the project's Code Analysis Tab. By checking the Enable Code Analysis box in this setting page, code analysis is then added to the build process and runs after the assembly compiles successfully.
Since Silverlight development is somewhat different from standard .Net development, I've had to modify my projects to take advantage of code analysis but not be warned about "false positives" - warnings that should be ignored. I typically do three things in my Silverlight projects for code analysis:
I disable these rules in the project's Code Analysis tab:
In the Properties/AssemblyInfo.cs I add two assembly attributes.
using System; using System.Resources; [assembly: CLSCompliant(false)] [assembly: NeutralResourcesLanguage("en-US")]
Since System.Windows.DependecyObject is not CLS compliant, most Silverlight assemblies will not be either. This is not a problem because Silverlight operates in its own secure sandbox and does not interoperate with other .Net assemblies. I added the NeutralResourcesLanguage attribute because of rule CA1824.
Typically in a project you will have proper nouns and cool-looking acronyms (like PiP or VoD). Since code analysis actually uses a dictionary to check the spelling of words, those terms are not found. What I like to do is add a code analysis dictionary to my project and set the Build Action to CodeAnalysisDictionary. The dictionary is just an XML file with the CodeAnalysisDictionary build action:
Then in the dictionary, I can add my words, deprecated terms, and cool-looking acronyms:
<?xml version="1.0" encoding="utf-8" ?> <Dictionary> <Words> <Unrecognized> <Word>Unrecog</Word> </Unrecognized> <Recognized> <Word>Scherotter</Word> <Word>Mindjet</Word> <Word>mmap</Word> </Recognized> <Deprecated> <Term PreferredAlternate="Best">Bestest</Term> <Term PreferredAlternate="Better">Gooder</Term> </Deprecated> </Words> <Acronyms> <CasingExceptions> <Acronym>PiP</Acronym> <Acronym>VoD</Acronym> </CasingExceptions> </Acronyms> </Dictionary>
Interestingly I could not find a XSD Schema describing this format either in Visual Studio or online. If you have the schema, then Visual Studio's intellisense helps you keep the syntax correct. One helpful thing that you can do with Visual Studio is have Visual Studio create a schema for you based on an XML file:
This creates the XSD file for you. Once you have created the XSD file, copy it to C:\Program Files (x86)\Microsoft Visual Studio 9.0\Xml\Schemas so that it can be easily used by the XML editor in Visual Studio. I have uploaded my version to the MSDN code gallery to give help you. If you want to use it:
You will then have intellisense for the Code Analysis dictionary that you are creating.
Now that it's all configured you should start using Code Analysis to make sure your code is clean and conformant. There is one false positive that I don't disable. If you create your own exception class, you will see CA1032 if you don't create the standard constructors (one warning for each missing constructor). If you try to fix these, you will find that CA1032 cannot be fixed for one of the constructors:
MSBUILD : warning : CA1032 : Microsoft.Design : Add the following constructor to 'MindMapException': protected MindMapException(SerializationInfo, StreamingContext).
Since SerializationInfo and StreamingContext are not implemented in Silverlight, there is no way to fix this issue. Since the other CA1032 issues are valid, I keep this warning enabled - I can live with one type of false positive but I document it in the source code class remarks:
/// <summary> /// MindMap Exception /// </summary> /// <remarks>Ignore Code Analysis warning CA1032 for protected MindMapException(SerializationInfo, StreamingContext)</remarks> public class MindMapException : Exception { ... }
I hope this helps you write better Silverlight code now.