将Keys对象强制转换为enum Direction对象

本文关键字:对象 enum 转换 Direction Keys | 更新日期: 2023-09-27 18:01:18

我创建了一个enum Direction,如下所示:

enum Direction { Up, Down, Left, Right }

现在这些方向被称为箭头键按下。现在我的KeyDown事件是这样的:

if (e.KeyCode == Keys.Up)
{
    moveDirection = Direction.Up;
}
else if (e.KeyCode == Keys.Left)
{
    moveDireciton = Direction.Left;
}
else if ...

有可能像(Direction)Keys.Up那样创建我自己的演员吗?

我知道我可以创建一个静态方法static Direction CastKeysToDirection(Keys k);,我对此很好,但我只是好奇是否有一种方法来实现我们自己的c#类型转换?

将Keys对象强制转换为enum Direction对象

如果您将enum定义为

enum Direction {
    Up = Keys.Up,
    Down = Keys.Down,
    Left = Keys.Left,
    Right = Keys.Right
}

,那么你的强制转换(Direction)Keys.Up应该工作,因为Keys.Up的数值与Direction.Up的数值是相同的。

遗憾的是,您不能像在class上那样在enum上提供真正的explicitimpilcit强制转换。

两个选项:

  • 只是转换,如果你确定值匹配(例如,因为你已经创建了Direction enum使用Keys.Up等作为值):

    moveDirection = (Direction) e.KeyCode;
    
  • 创建字典:

    private static readonly Dictionary<Keys, Direction> KeyToDirection =
        new Dictionary<Keys, Direction>
        {
            { Keys.Up, Direction.Up },
            { Keys.Left, Direction.Left },
            ...
        };
    

    然后在字典中查找已按下的键。(使用TryGetValue查找Keys -使用返回值检测字典中不存在的键)

当然,后者提供了一种更灵活的方法。它允许您有多个键都映射到同一个方向,例如

隐式强制转换是不可能的enum,但您可以在实现中使用隐式操作符,然后可能在进一步的工作中使用多态性和封装的一些好处(包括@Chris Sinclair的建议):

public abstract class Direction
{
    public static implicit operator Direction(Keys key)
    {
        switch (key)
        {
            case Keys.Up:
                return Up.Instance;
            case Keys.Down:
                return Down.Instance;
            case Keys.Left:
                return Left.Instance;
            case Keys.Right:
                return Right.Instance;
            default:
                throw new ArgumentOutOfRangeException();
        }
    }
}
public class Up : Direction
{
    private static readonly Up _Instance = new Up();
    public static Up Instance
    {
        get { return _Instance; }
    }
    private Up() {}
}
public class Down : Direction
{
    private static readonly Down _Instance = new Down();
    public static Down Instance
    {
        get { return _Instance; }
    }
    private Down() {}
}
public class Left : Direction
{
    private static readonly Left _Instance = new Left();
    public static Left Instance
    {
        get { return _Instance; }
    }
    private Left() {}
}
public class Right : Direction
{
    private static readonly Right _Instance = new Right();
    public static Right Instance
    {
        get { return _Instance; }
    }
    private Right() {}
}

用例:

Keys key = Keys.Up;
Direction direction = key; // Legal
if (direction == Up.Instance)
{
    // Do something
}
// Or add abstract methods to Direction class and invoke direction.DoWork()