1

I'm trying to make a generic function that converts a enum System.Array into a List of those enums, I can not know the type of the enum array. I have tried several ways but I have not been able to make it work. It would be something like this..., Thanks

    public static List<T> SArrayEnumToList<T>(System.Array arr){
        Type enumType = typeof(T);

        if(enumType.BaseType != typeof(Enum))
            throw new ArgumentException("T must be of type System.Enum");

        List<T> enumList = new List<T>(new T[arr.Length]);
        int i;
        for(i=0;i<arr.Length;i++) {
            enumList.Add(( T )Enum.Parse(enumType, arr.GetValue(i).ToString()));
        }

        return enumList;
    }
Cleger
  • 13
  • 3
  • `intVal` isn't the index, it's the value. Either use `foreach` properly, or switch to `for`. – Luaan Oct 08 '18 at 08:13
  • If you cannot know the type, why are you using the type then? – X39 Oct 08 '18 at 08:13
  • `foreach (T value in arr) enumList.Add(value);` fixes it. Do beware that you require the array to be one-dimensional, just easier to use T[] as the argument. Type inference now works. – Hans Passant Oct 08 '18 at 10:19
  • Thanks, I fixed. But this is not the problem. The problem is the System.Array is a Array of enums. – Cleger Oct 08 '18 at 18:53

2 Answers2

2

Assuming you have a array of int, this should work i guess

public static List<T> SArrayEnumToList<T>(int[] arr) where T : struct, IConvertible
{
    if (!typeof (T).IsEnum)
        throw new ArgumentException("T must be of type System.Enum");

    // cast to object first
    return arr.Cast<object>()
              .Cast<T>()
              .ToList();
}

// or

public enum Test
{
    blah,
    balh2,
    blah3
}

...

var results = ((Test[])(object)values).ToList();

Full Demo Here

TheGeneral
  • 79,002
  • 9
  • 103
  • 141
  • Thanks for your answer. I will try with int [] but I think it will not work because the function is called from another function that passes an object that is an Enums List. I need to use System.Array that does not allow me to use Linq. – Cleger Oct 08 '18 at 18:43
2

You only really need to use the Linq ToList() method:

var myEnumsList = myEnumsArray.ToList();

The documentation states that ToList() returns a list "that contains elements from the input sequence".

If you really want to break this functionality out to your own method, you may do this like following:

private static List<T> ToList<T>(T[] enums) where T : struct, IConvertible
{
    if (!typeof(T).IsEnum)
    {
        throw new ArgumentException("T must be an enum.");
    }
    return enums.ToList();
}

Constraining type of generic type T limits what types may be used when calling the method. Enum is a struct and implements IConvertible as discussed in here.

EDIT:

Since you really need to use System.Array. Iterate the System.Array, cast every value to generic type T and add to list before returning. Working example:

public static List<T> ToList<T>(Array array) where T : struct, IConvertible
{
    if (!typeof(T).IsEnum)
    {
        throw new ArgumentException("T must be an enum.");
    }
    List<T> enumValues = new List<T>();
    foreach (var enumValue in array)
    {
        enumValues.Add((T)enumValue);
    }
    return enumValues;
}

EDIT #2 Update after comments.

public static IList ToList(Array array)
{
    Type elementType = array.GetType().GetElementType();
    Type listType = typeof(List<>).MakeGenericType(new[] { elementType });
    IList list = (IList)Activator.CreateInstance(listType);
    foreach (var enumValue in array)
    {
        list.Add(enumValue);
    }
    return list;
}
kaffekopp
  • 2,551
  • 6
  • 13
  • 1
    While this might answer the authors question, it lacks some explaining words and links to documentation. Raw code snippets are not very helpful without some phrases around it. You may also find [how to write a good answer](https://stackoverflow.com/help/how-to-answer) very helpful. Please edit your answer. – hellow Oct 08 '18 at 09:32
  • Thanks for your answer!. The problem is that I can not use T [], I must use System.Array, the function is called from another function that passes an object that is a List of Enums. And the System.Array does not allow me to use Linq. I'm sure I'm doing something wrong but this works for all types except List of Enums. :/ – Cleger Oct 08 '18 at 18:33
  • I see. I edited my answer with a new example, tried and confirmed working. – kaffekopp Oct 08 '18 at 21:29
  • Thanks but I have the error, The type arguments for method `PACO.SArrayEnumToList(System.Array)' cannot be inferred from the usage. Try specifying the type arguments explicitly and I return to the same problem. – Cleger Oct 09 '18 at 09:41
  • Updated my answer, see Edit #2. – kaffekopp Oct 09 '18 at 10:58
  • You've done it!!! Thank you! I had been struggling with this for days! The last answer is the correct one, it works perfect! Thank you very much again! – Cleger Oct 10 '18 at 08:40