Cast Keys对象枚举Direction对象?

时间:2013-02-26 14:37:41

标签: c# casting enums

我已经像这样创建了一个枚举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#中实现我们自己的转换?

3 个答案:

答案 0 :(得分:7)

如果您将枚举定义为

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

然后你的演员(Direction)Keys.Up应该工作,因为Keys.Up下面的数值与Direction.Up下面的数值相同。

可悲的是,您无法像explicit那样在impilcit上提供真实的enumclass广播。

答案 1 :(得分:5)

两个选项:

  • 如果您确定值匹配(例如,因为您使用Direction等创建了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 - 使用返回值来检测词典中不存在的键。)

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

答案 2 :(得分:3)

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()