Lucina
Lucina

Reputation: 490

dynamic type casting behavior in multiple assemblies

In my program, I am using enumerations to represent the current state of an object. I would like to be able to cycle through the values of this enumeration one by one. The fact that the enum values are numerically sequential and begin with 0 is a given.

While attempting to write a function which increments the enumeration, looping if it has reached the end has yielded a problem.

public static TEnum IncrWrap<TEnum>(TEnum value)
{
    int len = Enum.GetNames(typeof(TEnum)).Length;
    dynamic wrapper = value;
    dynamic newValue = ((int)wrapper + 1) % len;
    return (TEnum)newValue;
}

If the IncrWrap method exists in the same assembly (project) as the object which calls it, it works perfectly. However, if I move it to another project (higher up so that more things can make use of it) and call it from the dll, I get a RuntimeBinderException when it attempts to cast wrapper to an int with the message "Cannot convert type 'System.Enum' to 'int'".

Whats up? I don't see why calling the function from a different assembly would cause the function to behave so differently. Is there something about dynamic I don't understand? It would be nice to not have to use reflection to do this.

Upvotes: 0

Views: 208

Answers (1)

Phil Klein
Phil Klein

Reputation: 7514

Unfortunately enumerations pose some problems here. First of all an enumeration can have any integral type, other than char. Secondly, there is no guarantee that enumerations have incrementally increasing values of the underlying type. Lastly, the C# language does not support generic type constraints of System.Enum which would be somewhat helpful. With all that said, I believe that you can solve your problem a bit differently:

public static TEnum NextEnum<TEnum>(TEnum value)
{
    if (!typeof(TEnum).IsEnum)
        throw new ArgumentException("Expected type of System.Enum", "value");

    var values = Enum.GetValues(typeof (TEnum));
    var index = Array.IndexOf(values, value);
    return (TEnum)Enum.ToObject(typeof (TEnum), values.GetValue((index + 1) % values.Length));
}

I'm actually surprised that you were able to get that to work using your dynamic solution.

Upvotes: 1

Related Questions