-1

I wanted to make a function to get the key. But I did not know how to make, that it will get my Key[CODE].

public bool GetKey(ConsoleKeyInfo cki, int key)
{   
    // here I don't know what to type
    if (Console.ReadKey(true).Key == ConsoleKey.) 
    {
        return true;
    } 
    else
    {
        return false;
    }
} 

I did try using it like a array:

if (Console.ReadKey(true).Key == ConsoleKey[key]) { 
    // Code To Be Excecuted
}
IVSoftware
  • 5,732
  • 2
  • 12
  • 23
Inferno
  • 11
  • 4
  • 1
    Enums are ints, see https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/enum – Sorceri Dec 16 '22 at 17:36
  • https://stackoverflow.com/questions/29482/how-do-i-cast-int-to-enum-in-c – Renat Dec 16 '22 at 17:37
  • 1
    This StackOverflow [answer](https://stackoverflow.com/questions/74630377/how-to-accept-the-user-response-either-as-an-int-or-a-char-or-a-string-c-sharp/74631038#74631038) shows one good way to interpret the result of `Console.ReadKey`. Does this help answer your question? – IVSoftware Dec 16 '22 at 17:53

2 Answers2

1

The enum is by default an integer, you only need to cast it.

Let's supposed you want to use any numeric value to convert to your enum type, and it's set as a short by default (if you do not add the : short then : int is assumed, code is verbose and can be optimized):

public enum Enumeration : short
{
  fist = 1,
  second,
  third,
  fourth,
  fifth,
  sixth,
  seventh,
  eighth,
}

public class verify {
  public Enumeration fromInt(int i)
  {
    Enumeration result;
    result = (Enumeration)i;
    return result;
  }

  public Enumeration fromLong(long l)
  {
    Enumeration result;
    result = (Enumeration)l;
    return result;
  }

  public Enumeration fromDouble(double d)
  {
    Enumeration result;
    result = (Enumeration)d;
    return result;
  }

  public Enumeration fromAnything(object o)
  {
    Enumeration result;
    try
    {
      result = (Enumeration)o;
    }
    catch (Exception ex)
    {
      if(!Enum.TryParse<Enumeration>($"{o}",true, out result))
      {
        var typeName = o?.GetType().Name ?? "NULL";
        throw new Exception($"There is no way to cast object {typeName} into a valid Enumeration value.", ex);
      }
    }
    return result;
  }
}

If You test those methods with the following XUnit test (those are only to emphasize the casting, the last to accept almost all different cases):

[Fact]
public void enumTest()
{
  var v = new verify();
  var fromInt = v.fromInt(5);
  var fromLong = v.fromLong(6);
  var fromDouble = v.fromDouble(7);
  var fromAnything = v.fromAnything("second");
  _output.WriteLine($"fromInt = '{fromInt}'");
  _output.WriteLine($"fromLong = '{fromLong}'");
  _output.WriteLine($"fromDouble = '{fromDouble}'");
  _output.WriteLine($"fromAnything = '{fromAnything}'");

  fromAnything = v.fromAnything("12345");
  _output.WriteLine($"fromAnything = '{fromAnything}'");
}

The test results are:

Standard Output: 
    fromInt = 'fifth'
    fromLong = 'sixth'
    fromDouble = 'seventh'
    fromAnything = 'second'
    fromAnything = '12345'

Bottom line, just cast your integer value with your enum type if you are sure values are compatible and in range.

Note that the last value in the test is out of range, but even in dotnet6, do not rise an exception because 12345 can be accept by a short.

1

Your question is Can I Get An Enum From An Int? The answer is yes you can convert an int to an Enum (with upper-case Enum is a class):

// Works. But is it ideal for the code you posted?
Enum someEnum = (Enum)Enum.ToObject(typeof(ConsoleKey), 49);

The value of someEnum is now ConsoleKey.D1.


You can also convert an int to an enum (with lower case it is a type):

ConsoleKey key = (ConsoleKey)49;

The value of key is now ConsoleKey.D1.


You can also do this in reverse which is (int)ConsoleKey.D1 to get a value of 49.


However let's look at your code which shows a call to ReadKey. The type returned from this method is a ConsoleKeyInfo whose job is to give you all the information you need about the key that was pressed.

Just because you can convert between the two types doesn't mean that you should. You have choices!

One good way to take advantage of the format that it returns is to switch on the value of Key to perform the action you want. This example is a menu-driven game and the menu is looking for a key between 1 and 5.


The ConsoleKey.Key value for the '1' key is ConsoleKey.D1 (and so on...).

static void Main(string[] args)
{
    // Loop until a valid int is received.
    bool exit = false;
    while (!exit)
    {
        displayMenu();

        ConsoleKeyInfo keyInfo = Console.ReadKey();

        switch (keyInfo.Key)
        {
            case ConsoleKey.D1: setup(); break;
            case ConsoleKey.D2: createCharacter(); break;
            case ConsoleKey.D3: changeAvatar(); break;
            case ConsoleKey.D4: editProfile(); break;
            case ConsoleKey.D5: play(); break;
            case ConsoleKey.Escape: exit = true; break;
            default:
                Console.Clear();
                Console.WriteLine("Please enter a number 1-5");
                Thread.Sleep(1000);
                break;
        }
    }
}

Every loop iteration displays a menu:

console

private static void displayMenu()
{
    Console.Clear();
    Console.WriteLine("1 - Setup");
    Console.WriteLine("2 - Create Character");
    Console.WriteLine("3 - Change Avatar");
    Console.WriteLine("4 - Edit Profile");
    Console.WriteLine("5 - Play");
    Console.WriteLine();
    Console.WriteLine("Escape key to Exit");
}

And based on the value of ReadKey it will exec one of the five actions or it will exit the game.

private static void setup() { }
private static void createCharacter() { }
private static void changeAvatar() { }
private static void editProfile() { }
private static void play() { }
IVSoftware
  • 5,732
  • 2
  • 12
  • 23