views:

389

answers:

1

I have a piece of C# code that add the values of an enum to a drop down list by type. It requires that it be called with T1 being an enum type, although I cannot specify this as a type constraint because enums are special case in which this isn't possible. This is not a major concern as this is only used internally and is documented.

Description is an extension on System.Enum that returns the value of the DescriptionAttribute of the value of the enum or the ToString of the value if it's not specified.

Because of this I must cast to System.Enum in the Cast part of the LINQ statement and not to T1 otherwise the Description extension isn't available.

public static void AddEnum<T1>(this System.Web.UI.WebControls.DropDownList me)
{
    Type t = Enum.GetUnderlyingType(typeof(T1));
    var l = Enum.GetValues(typeof(T1))
                .Cast<System.Enum>()
                .Select(x => new ListItem(x.Description(),
                                          Convert.ChangeType(x, t)
                                                 .ToString()));
    me.Items.AddRange(l.ToArray());
}

This is fine and works in Visual Studio 2008s web development server but fails with a cast exception when run on IIS 6. It is run with an unchanging, hardcoded enumerable as the type parameter to populate ASP pages.

System.InvalidCastException: Invalid cast from '%namespace.class+nameofenum%' to 'System.Enum'. at System.Convert.DefaultToType(IConvertible value, Type targetType, IFormatProvider provider) at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider) at System.Linq.Enumerable.d__b01.MoveNext() at System.Linq.Enumerable.<SelectIterator>d__d2.MoveNext() at System.Linq.Buffer1..ctor(IEnumerable1 source) at System.Linq.Enumerable.ToArrayTSource at AddEnumT1

(namespace/classname obscured by me)

I am unable to test it on other versions of IIS but it seems very strange that the development version doesn't match the the production system. Does anyone know why this is?

+5  A: 

Shot in the dark. One of the platforms is running 3.5 RTM and the other is running 3.5 SP1. If so you are likely running into a breaking change introduced in 3.5SP1 that altered the way .Cast() operates. See these posts for more details

JaredPar
Nice work, they are running different versions but unfortunately we won't be upgrading the production site soon.Thanks for the help.
Toby