-1

I have a list of enums that i filled, and for many reason i casted it to an object ob. A function receive this object and try to parse it as a generic Enum.

 List<MyEnum> mList = new List<MyEnum>();
  // i fill my list
  mList.Add(MyEnum.FirstValue);
  //...

  object ob = mList;
  if (ob.GetType().IsGenericType && ob.GetType().GetGenericTypeDefinition() == typeof(List<>))
  {
    Type subTypeOb = ob.GetType().GenericTypeArguments.Single();
    if (subTypeOb.IsEnum)
    {
      foreach (Enum subOb in (List<Enum>)ob)
      {
        // do stuff
      }
    }
  }

The thing is, i want to cast it back to a generic List of Enum so that i can use it. I don't want and don't need to cast it back to it's original enum (it can be many other enum).

But i alwais get an error on: (List<Enum>)ob:

can't cast object 'System.Collections.Generic.List1[MyEnum]' en type 'System.Collections.Generic.List1[System.Enum]'

I can't cast it to a List, i can't find a way to cast it in a list of anything generic. What i don't understand is : between a generic Enum and MyEnum, there isn't a lot of difference, it's the same memory space.

Could you help me figure out?

---- EDIT --- More Infos Oh god i'm so stupid, i forgot to :using System.Collections;

Now i can do : List<Enum> enums = (ob as IList).Cast<Enum>().ToList();

And it work perfectly fine ! Thanks you stranger.

Samael
  • 61
  • 1
  • 9
  • 1
    you can cast `ob` to `IList` of course it will cause boxing – Selvin Oct 15 '20 at 15:25
  • 2
    A list of `MyEnum` is not the same as a list of `System.Enum`. If your cast succeeded, then someone could add any `enum` to your list through the cast-ed reference. Generally, when I'm working with Reflection, I end up using the non-generic `IList` type: List implements it, and it allows me to operate on the list as a list – Flydog57 Oct 15 '20 at 15:25
  • 1
    C# does not allow generic type variance when it involves value types; so, yes, there is a big difference between `List` and `List`, same as `List` and `List`, etc. I don't see how you can avoid boxing in your specific scenario (`MyEnum` to `Enum` is a boxing conversión to begin with), so why don't you simple iterate an `IList`? What does strongly typing the list members to `Enum` help you with? – InBetween Oct 15 '20 at 15:56
  • Flydog57 and InBetween had a good point, thanks, i am now looking at `IList` and how i can use it. The things is, i'm filling an ihm based on the type of information i received, directly using `Enum` would help me parse every item of the list, just to make a `.GetType()` to later make an `Enum.getValues()`. (since `ob.GetType().GenericTypeArguments.Single()` already told me that they were enums) (I understand the relative stupidity of making a `GetType()` on a `Enum`, but it's useful with an `object`, so i had hope. – Samael Oct 15 '20 at 16:03

1 Answers1

1

Reading comments I think you are simpy looking for the extension method Cast:

var o = //some List<myEmum>;
List<Enum> enums = (o as IList).Cast<Enum>().ToList();

foreach (var e in enums)
{
    //whatever you need to do with e
}

And now you can iterate a List<Enum>. Of course, Cast is just a simple projection, you can do it manually inside your loop:

var listOfObjects = o as IList;
foreach (var o in listOfObjects)
{
    var e = (Enum)o;
    //whatever you need to do with e
}

In both cases you are incurring in boxing operations. MyEnum is a value type, and you are implictly casting (boxing) all members of the "untyped" list to object when interacting with the non generic IList. But, because you seem to want to actually use Enum typed members, and taking into account that MyEnum to Enum is already a boxing conversion, boxing per se doesn't seem to be an issue you are worryied about (or aware of).

InBetween
  • 32,319
  • 3
  • 50
  • 90