Friday, October 5, 2007

Compiler warnings from generated code

Although I believe strongly in treating warnings as errors, on rare occasions I get compiler warnings from generated code.  Examples of generated code include the designer code files for Windows and Web forms, XAML, etc.  Warnings in those files are easily removed, as it's almost always related to files coded by the programmer.

I recently hit a really strange compiler warning while using the aspnet_compiler tool, which compiles the ASPX, ASCX, and other content.  Part of this process is to parse the ASPX and ASCX files and create C# files from those.  However, I started getting very strange warnings from the precompilation:

c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\
  Temporary ASP.NET Files\ecommstore\5c1cb822\
  6aeabbae\App_Web_d0wxlov2.10.cs(87):
  warning CS0108: Ecomm.Login.Profile' hides inherited member 'Foundation.Core.Web.PageBase.Profile'. 
  Use the new keyword if hiding was intended.

Shadowing warnings aren't new to me, but this one is especially strange since it came from ASP.NET.  Specifically, a property created in an auto-generated class conflicts with a property in a global base Page class we use for all of our ASP.NET pages.  The base Page class is created by another team here, which provides all sorts of logging, etc.  I can't touch that one, nor would I want to, as it is used company-wide.  That base Profile property isn't virtual either.

But how can I get rid of the other one?  I tried all sorts of magic:

  • Shadowing and exposing as virtual (the subclass and override method)
  • Shadowing and preventing overriding by using the new and sealed modifiers on that property

Nothing worked.  No matter what, the Profile property would get created.  What does that code file actually look like?  Here's the more interesting part:

public partial class Login : System.Web.SessionState.IRequiresSessionState {        
    
    #line 12 "E:\dev\ecommstore\build\Debug\ecommstore\Login.aspx"
    protected global::System.Web.UI.WebControls.PlaceHolder mainPlaceholder;
    
    #line default
    #line hidden
    
    protected System.Web.Profile.DefaultProfile Profile {
        get {
            return ((System.Web.Profile.DefaultProfile)(this.Context.Profile));
        }
    }
    
    protected ASP.global_asax ApplicationInstance {
        get {
            return ((ASP.global_asax)(this.Context.ApplicationInstance));
        }
    }
}

There's the offender, the auto-generated Profile property.  Looking back at some older build logs, I notice that this warning didn't show up until we migrated to ASP.NET 2.0.  One of the new features of ASP.NET 2.0 is the Profile properties.  ASP.NET 2.0 profiles allow me to create strongly-typed custom profiles for customers and let them be integrated into our ASP.NET pages, be automatically stored and retrieved, etc.  If I defined custom properties for my profile, then a dynamically created Profile class would be used (instead of the DefaultProfile type).

However, we don't use Profiles, so I can just turn them off in our web.config file:

<profile enabled="false" />

By turning Profiles off, the Profile property is never created in the auto-generated code.  The warnings go away, and our problem is solved.

There are several other instances of these new ASP.NET 2.0 features in auto-generated code causing naming collisions with existing properties when migrating from ASP.NET 1.1.  The solution was always to rename your properties, but since I couldn't do that, turning Profiles off did the trick.

2 comments:

Anonymous said...

I've got the same problem where I'm inheriting from a base page.

Since I'm not using profile, that worked exactly as you said. Thanks.

But what about ApplicationInstance? I'm getting a compiler warning for ApplicationInstance in the same way and for the same reasons that I got one for Profile. Is there a workaround for this?

Thanks,
Michael

Jimmy Bogard said...

@Michael

Hmmm...tough one. I think you have 2 choices -

- Rename the base class property
- Ignore the warning

Sometimes you have to learn to live with the warnings - not always the best choice, but sometimes the only one.