1

I have the following generic unction which takes an Enum type, displays a list of the 'options', then loops/waits for the user to select a viable option:

public static T AskGenericType<T>(string message) where T : Enum
{
    //Display options
    Console.WriteLine(message);
    foreach (var item in Enum.GetValues(typeof(T)))
    {
        Console.WriteLine($"[{(int)item}] {item}");
    }

    var returnInt = TryParseInput();

    while (true)
    {
        if (Enum.IsDefined(typeof(T), returnInt))
            break;
        //Cannot parse input as one of the choices presented from the Enum
        Console.WriteLine($"Please choose from one of the options.");
        returnInt = TryParseInput();
    }

    return (T)returnInt; //<---this produces the compile error
}

private static int TryParseInput()
{
    int returnInt;
    while (!int.TryParse(Console.ReadLine(), out returnInt))
    {
        //Cannot parse input as an integer
        Console.WriteLine($"Selection is not a number. Please try again.");
    }

    return returnInt;
}

I can get the function to work if I remove the <T> generics altogether from the function definition as well as inside the code block. The error I get is:

Cannot convert type 'int' to 'T'

I'm looking for suggestions on how I can preserve the generic nature of the function with the loop as I have several Enum types to iterate through and I don't want to have to duplicate code for each one.

Update: I feel this is not a duplicate due to the nature in which I'm referencing the integer of the Enum and the other referenced duplicates are not trying to parse an Enum at all.

Jason Shave
  • 2,462
  • 2
  • 29
  • 47
  • 3
    Possible duplicate: https://stackoverflow.com/questions/29482/how-to-cast-int-to-enum – Sweeper Jan 04 '20 at 22:12
  • You need to constrain T to enum https://stackoverflow.com/questions/79126/create-generic-method-constraining-t-to-an-enum – Joel Wiklund Jan 04 '20 at 22:16
  • @JoelWiklund OP clearly did that in the very first line – Sweeper Jan 04 '20 at 22:18
  • I'm not sure I understand why you try to cast your `resultInt` to a `T` which extend an `Enum`. Your function return a `T` not an `int`. Change the return type of your function `AskGenericType` to `int` and remove the cast. – Philippe B. Jan 04 '20 at 22:19
  • 1
    Try ```return (T)Enum.ToObject(typeof(T), returnInt);``` – Joel Wiklund Jan 04 '20 at 22:32
  • 2
    Does this answer your question? [Cast Int to Generic Enum in C#](https://stackoverflow.com/questions/10387095/cast-int-to-generic-enum-in-c-sharp) – Simply Ged Jan 04 '20 at 22:40

1 Answers1

2

Change to return (TEnum)Enum.ToObject(typeof(TEnum), returnInt);. More info here.

public class Program
{
    public static void Main()
    {
        var favoriteColor = AskGenericType<Color>("What is your favorite color?");
        Console.WriteLine(favoriteColor);

        var favoriteCar = AskGenericType<Car>("What is your favorite car?");
        Console.WriteLine(favoriteCar);
    }

    enum Color
    {
        Red,
        Blue,
        Yellow
    }

    enum Car
    {
        Volvo,
        Lamborghini,
        Ferrari
    }

    public static TEnum AskGenericType<TEnum>(string message) where TEnum : struct, Enum
    {
        //Display options
        Console.WriteLine(message);
        foreach (var item in Enum.GetValues(typeof(TEnum)))
        {
            Console.WriteLine($"[{(int)item}] {item}");
        }

        var returnInt = TryParseInput();

        while (true)
        {
            if (Enum.IsDefined(typeof(TEnum), returnInt))
                break;
            //Cannot parse input as one of the choices presented from the Enum
            Console.WriteLine($"Please choose from one of the options.");
            returnInt = TryParseInput();
        }

        return (TEnum)Enum.ToObject(typeof(TEnum), returnInt);
    }

    private static int TryParseInput()
    {
        int returnInt;
        while (!int.TryParse(Console.ReadLine(), out returnInt))
        {
            //Cannot parse input as an integer
            Console.WriteLine($"Selection is not a number. Please try again.");
        }

        return returnInt;
    }
}

Output

What is your favorite color?
[0] Red
[1] Blue
[2] Yellow
1
Blue
What is your favorite car?
[0] Volvo
[1] Lamborghini
[2] Ferrari
0
Volvo
Joel Wiklund
  • 1,697
  • 2
  • 18
  • 24