Both Code Analysis, FxCop and Code Metrics make extensive use of CompilerGeneratedAttribute and GeneratedCodeAttribute to distinguish between user-written code and tool and compiler generated code.

The following describes this behavior:

Code Analysis in Visual Studio 2005 and FxCop 1.35

- Compiler Generated. Does not raise warnings against compiler generated code. Uses an algorithm (mainly based on the name) to determine if code is compiler generated.
- Tool Generated. Raises warnings against nearly all tool generated code. Uses an algorithm to turn off particular rules against code marked with GeneratedCodeAttribute and generated by specific code generators.

Code Analysis in Visual Studio 2008 and FxCop 1.36

- Compiler Generated. Does not raise any warnings against code marked with the CompilerGeneratedAttribute. Also users an algorithm to determine if other code is compiler generated.
- Tool Generated. Does not raise warnings against code marked with the GeneratedCodeAttribute if Suppress results from generated code is turned on (the default).

Code Metrics in Visual Studio 2008

- Compiler Generated. Does not display or generate metrics for code marked with the CompilerGeneratedAttribute. Also users an algorithm to determine if other code is compiler generated.
- Tool Generated. Does not display or generate metrics for code marked with the GeneratedCodeAttribute.

Unfortunately, there are many cases of incorrect usage of these attributes both internally and externally of Microsoft, and this blog post is an attempt to make things a little clearer in the correct application of these attributes.

CompilerGenerateAttribute

This attribute is for compiler use only and indicates that a particular code element is compiler generated. This should never be used in source code whatsoever. In fact, some users believe that usage of it should be a compilation error. I tend to agree.

For example, the following is an incorrect usage of this attribute (this is not compiler generated code):

/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[DebuggerNonUserCodeAttribute()]
[
CompilerGeneratedAttribute()]
internal class Resources
{
    private ResourceManager resourceMan;
    private CultureInfo resourceCulture;

    [
SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
    internal Resources()
    {
    }

    /// <summary>
    /// Returns the cached ResourceManager instance used by this class.
    /// </summary>
    [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
    internal static ResourceManager ResourceManager
    {
        get
        {
            if ((resourceMan == null))
            {
                ResourceManager temp = new ResourceManager("WindowsApplication1.Properties.Resources", typeof(Resources).Assembly);
                resourceMan = temp;
            }

            return resourceMan;
        }
    }

    /// <summary>
    /// Overrides the current thread's CurrentUICulture property for all
    /// resource lookups using this strongly typed resource class.
    /// </summary>
    [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
    internal static CultureInfo Culture
    {
        get { return resourceCulture; }
        set { resourceCulture = value; }
    }
}

GeneratedCodeAttribute

This attribute is for use by custom tools that generate code. It should only be applied to code that is re-generated over and over and should not be used by templates that the user is expected to modify. Nor should it be applied at the type level if the type being generated is a partial class. In this situation, it should be applied only against the individual members that are contained within the generated part of the type.

For example, the following shows the incorrect usage of this attribute (it is being applied at the type level to a partial class):

[GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "9.0.0.0")]
internal sealed partial class Settings : ApplicationSettingsBase
{
    private static Settings defaultInstance = ((Settings)(ApplicationSettingsBase.Synchronized(new Settings())));

    public static Settings Default
    {
        get { return defaultInstance; }
    }

    [UserScopedSettingAttribute()]
    [
DebuggerNonUserCodeAttribute()]
    [
DefaultSettingValueAttribute("")]
    public string MySetting
    {
        get { return ((string)(this["MySetting"])); }
        set { this["MySetting"] = value; }
    }
}

The following shows the correct usage of this attribute:

internal sealed partial class Settings : ApplicationSettingsBase
{
    [GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "9.0.0.0")]
    private static Settings defaultInstance = ((Settings)(ApplicationSettingsBase.Synchronized(new Settings())));

    [GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "9.0.0.0")]   
    public
static Settings Default
    {
        get { return defaultInstance; }
    }

    [GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "9.0.0.0")]
   
[
UserScopedSettingAttribute()]
    [
DebuggerNonUserCodeAttribute()]
    [
DefaultSettingValueAttribute("")]
    public string MySetting
    {
        get { return ((string)(this["MySetting"])); }
        set { this["MySetting"] = value; }
    }
}

Unfortunately, due to the sheer number of teams within Microsoft that release tool generators and templates (there are hundreds within Visual Studio itself), it becomes impossible to track down all usages of these.

Therefore, if you encounter any incorrect usages of these attributes, free feel to head over to Microsoft Connect and tell us about it.