unity3d 无法在Unity的Switch语句中使用静态对象

3qpi33ja  于 2023-01-09  发布在  其他
关注(0)|答案(3)|浏览(161)

我有Unity 2021,所以我相信它使用C#版本〉7。不知何故,我不能在Switch/Case语句中使用静态对象。

private Position getStartingPosition(Direction direction) {
    switch (direction) {
      case Direction Direction.EAST:
        return new Position(-1, height / 2);
      case Direction Direction.NORTH:
        return new Position(width / 2, height);
      case Direction Direction.WEST:
        return new Position(width, height / 2);
      case Direction Direction.SOUTH:
        return new Position(width / 2, -1);
      default:
        throw new System.Exception("Impossible");
    }
  }

和方向类:

public class Direction
{
    static public readonly Direction EAST = new Direction(1, 0);
    static public readonly Direction NORTH = new Direction(0, -1);
    static public readonly Direction WEST = new Direction(-1, 0);
    static public readonly Direction SOUTH = new Direction(0, 1);

...

我得到的错误是:

Grid.cs(38,31): error CS1003: Syntax error, ':' expected
Grid.cs(38,31): error CS1513: } expected
Grid.cs(38,36): error CS1003: Syntax error, ':' expected
Grid.cs(38,36): error CS1513: } expected
Grid.cs(40,31): error CS1003: Syntax error, ':' expected
Grid.cs(40,31): error CS1513: } expected

我哪里做错了?

3vpjnl9f

3vpjnl9f1#

case语句应该是var _ when direction.Equals(Class.VALUE),但没有声明。但是Direction也是一个对象,因此可以使用此语句的一个选项:

switch (direction) {
  case var _ when direction.Equals(Direction.EAST):
    return new Position(-1, height / 2);
  case var _ when direction.Equals(Direction.NORTH):
    return new Position(width / 2, height);
  case var _ when direction.Equals(Direction.WEST):
    return new Position(width, height / 2);
  case var _ when direction.Equals(Direction.SOUTH):
    return new Position(width / 2, -1);
  default:
    throw new System.Exception("Impossible");
}

并使用类似以下的方法实现接口IEquatable<Direction>

public bool Equals(Direction otherDirection)  
{  
    return (this.x == otherDirection.x && this.y == otherDirection.y);  
}

其中xy是类中的值,用于确定两个对象是否相等。

t3psigkw

t3psigkw2#

Unity uses C# 9.0。您只能打开常量和模式(其中常量是常量模式)。
我们可以使用一个位置模式来做测试。要使用它,我们必须在类中添加一个解构器

public class Direction
{
    public Direction(int east, int south)
    {
        East = east;
        South = south;
    }

    public int East { get; }
    public int South { get; }

    public void Deconstruct(out int east, out int south)
    {
        east = East;
        south = South;
    }
}

然后我们可以这样切换:

switch (direction) {
    case (1, 0):
        return new Position(-1, height / 2);
    case (0, -1):
        return new Position(width / 2, height);
    case (-1, 0):
        return new Position(width, height / 2);
    case (0, 1):
        return new Position(width / 2, -1);
    default:
        throw new ArgumentException("Impossible", nameof(direction));
}

另一个可能的模式是不需要解构器的元组模式

switch ((direction.East, direction.South)) {
    case (1, 0):
        return new Position(-1, height / 2);
    case (0, -1):
        return new Position(width / 2, height);
    case (-1, 0):
        return new Position(width, height / 2);
    case (0, 1):
        return new Position(width / 2, -1);
    default:
        throw new ArgumentException("Impossible", nameof(direction));
}

另一种可能性是使用常量模式来接通enum常量:

public enum DirectionKind
{
    None,
    East,
    North,
    West,
    South
}

然后,我们向Direction类中添加一个如下所示的属性

public DirectionKind DirectionKind { get; }

我让你自己初始化它,然后我们这样切换:

switch (direction.DirectionKind) {
    case DirectionKind.East:
        return new Position(-1, height / 2);
    case DirectionKind.North:
        return new Position(width / 2, height);
    case DirectionKind.West:
        return new Position(width, height / 2);
    case DirectionKind.South:
        return new Position(width / 2, -1);
    default:
        throw new ArgumentException("Impossible", nameof(direction));
}

最后,让我们使用一个属性模式

switch (direction) {
    case { East: 1, South: 0 }:
        return new Position(-1, height / 2);
    case { East: 0, South: -1 }:
        return new Position(width / 2, height);
    case { East: -1, South: 0 }:
        return new Position(width, height / 2);
    case { East: 0, South: 1 }:
        return new Position(width / 2, -1);
    default:
        throw new ArgumentException("Impossible", nameof(direction));
}

从C# 9.0开始,我们有了switch expression,与switch语句相比,它的语法简化了:

// Positional pattern with deconstructor
return direction switch {
    ( 1,  0) => new Position(-1, height / 2),
    ( 0, -1) => new Position(width / 2, height),
    (-1,  0) => new Position(width, height / 2),
    ( 0,  1) => new Position(width / 2, -1),
    _ => throw new ArgumentException("Impossible", nameof(direction)),
};
// Tuple pattern
return (direction.East, direction.South) switch {
    ( 1,  0) => new Position(-1, height / 2),
    ( 0, -1) => new Position(width / 2, height),
    (-1,  0) => new Position(width, height / 2),
    ( 0,  1) => new Position(width / 2, -1),
    _ => throw new ArgumentException("Impossible", nameof(direction)),
};
// Constant pattern on enum constants
return direction.DirectionKind switch {
    DirectionKind.East  => new Position(-1, height / 2),
    DirectionKind.North => new Position(width / 2, height),
    DirectionKind.West  => new Position(width, height / 2),
    DirectionKind.South => new Position(width / 2, -1),
    _ => throw new ArgumentException("Impossible", nameof(direction)),
};
// Property pattern
return direction switch { 
    { East:  1, South:  0 } => new Position(-1, height / 2), 
    { East:  0, South: -1 } => new Position(width / 2, height),
    { East: -1, South:  0 } => new Position(width, height / 2), 
    { East:  0, South:  1 } => new Position(width / 2, -1),
    _ => throw new ArgumentException("Impossible", nameof(direction)),
};

对于target typed new,我们可以写(以位置模式为例):

return direction switch {
    ( 1,  0) => new (-1,        height / 2),
    ( 0, -1) => new (width / 2, height    ),
    (-1,  0) => new (width,     height / 2),
    ( 0,  1) => new (width / 2, -1        ),
    _ => throw new ArgumentException("Impossible", nameof(direction)),
};
13z8s7eq

13z8s7eq3#

已经在这里得到了回答:Switch statement with static fields
我改成了

switch (direction) {
      case var _ when direction == Direction.EAST:
        return new Position(-1, height / 2);
      case var _ when direction == Direction.NORTH:
        return new Position(width / 2, height);
      case var _ when direction == Direction.WEST:
        return new Position(width, height / 2);
      case var _ when direction == Direction.SOUTH:
        return new Position(width / 2, -1);
      default:
        throw new System.Exception("Impossible");
    }

相关问题