1

我仍在学习 C# 编程的诀窍。我正在尝试编写一个应用程序来解决骑士之旅,但在尝试为骑士获得可能的未来职位时遇到了一些悲伤。

对于职位,我使用了一个非常简单的结构:

public struct Position
{
    public enum BoardRank { A = 1, B, C, D, E, F, G, H }; 
    public BoardRank X;
    public int Y;
}

在骑士课中,我的PossibleMoves()方法是这样开始的:

public List<Position> PossibleMoves(Position position)
{
    List<Position> positions = new List<Position>();
    int[] multiply = new int[]{1, -1};
    foreach (int times in multiply)
    {
        try{
            Position possible = new Position();
            possible.X = position.X + (Behaviour.X * times);
            possible.Y = position.Y + (Behaviour.Y * times);
            positions.Add(possible);
        }
    ...

对于 position = A1 和 times = -1,您可以看到 Behaviour.X 是如何迅速超出范围的,但我认为这会被 try 块拾取。

我尝试{get; set;}在枚举声明上添加一个,但这在 VS2010 中引发了一些无用的语法错误。

还有什么我可以在这里尝试阻止我的枚举超出范围的吗?

4

2 回答 2

9

我认为这会被 try 块拾取。

没有。C# 中的枚举实际上是“命名数字”。它们不是该类型的完整值集。

还有什么我可以在这里尝试阻止我的枚举超出范围的吗?

您可以使用Enum.IsDefined来检查原始枚举中是否存在值。我个人会停止使用公共字段,而是使Position不可变 - 然后验证构造函数中的值。您还可以使用一些方法,例如WithX根据当前值返回一个新值,只需X更改即可。尽管您拥有公共字段,但您永远无法相信任何特定值都是有效的。

于 2013-05-17T09:50:37.453 回答
1

使用模数将值保持在特定范围内可能很有用:

possible.X = (position.X + (Behaviour.X * times)) % ((int)BoardRank.H + 1);

这样我不确定枚举是否是这里的最佳解决方案,因为无论如何我们都在使用整数。这些数字必须是一个没有间隙的序列,并且您必须确保采用最高定义的枚举值加一。因此,如果将 a 添加I到枚举中,则需要更改模块。

这里我有一个非常简单的程序来说明它是如何工作的:

enum Foo { A, B, C }

static void Main(string[] args)
{
    for (int i = 0; i < 10; i++)
    {
        Console.WriteLine(i % ((int)Foo.C + 1));
    }
}

如您所见,我们取i C + 1,使C' 的整数值成为实际范围的最大值。这是输出:

0, 1, 2, 0, 1, 2, 0, 1, 2, 0

于 2013-05-17T09:50:24.153 回答