本质上是二维枚举?

时间:2019-05-29 23:02:07

标签: c# software-design

不确定如何表达这句话,但是我有一个叫Lane的类,用于道路的不同车道。

Lane有两个部分-方向(左,右或其他的Enum),然后是数字(一个整数)。所以通道看起来像这样:L1,L2,R1,R3等。

每个车道只能有一个车道类别实例。 L1不应该存在两次。

因此,我希望能够通过键入Lane.L1或Lane.R4等来为对象的Lane分配枚举的方式进行分配。我目前必须使用一种方法来查找现有的与我要引用的车道相对应的车道对象。

这是做得更好的一种方法吗?就像通过简单地输入lane = Lane.L1一样,除了使Lane类具有私有构造函数并为每个可能的Lane手动创建公共Getter并为Lane类分配静态构造函数中的引用之外,还可以?

这是车道类别的当前状态:

public enum Direction { INCREASING = 1, DECREASING = 2, BOTH = 3, OTHER = 4, UNSPECIFIED = 5 }
public class Lane : IComparable
{
    public Direction Direction;
    public int Number = 1;
    public Lane(Direction direction, int number = 1)
    {
        Direction = direction;
        Number = number;
    }

    public override string ToString()
    {
        if (Direction == Direction.UNSPECIFIED)
        {
            return Direction.AsCharLR().ToString();
        }
        return Direction.AsCharLR() + Number.ToString();
    }

    public override bool Equals(object obj)
    {
        if (obj is Lane)
        {
            Lane l = obj as Lane;
            return Direction == l.Direction && Number == l.Number;
        }
        return false;
    }

    public override int GetHashCode()
    {
        return (int)Direction * 100 + Number;
    }

    public static Lane Parse(char lane)
    {
        lane = char.ToUpper(lane);
        switch (lane)
        {
            case 'L':
            case 'I':
                return new Lane(Direction.INCREASING);
            case 'R':
            case 'D':
                return new Lane(Direction.DECREASING);
            case 'B':
                return new Lane(Direction.BOTH);
            case 'U':
                return new Lane(Direction.UNSPECIFIED);
            case 'O':
            default:
                return new Lane(Direction.OTHER);
        }
    }
    public static Lane Parse(string text)
    {
        Lane lane = Parse(text[0]);
        lane.Number = int.Parse(text.Substring(1));
        return lane;
    }

    public int CompareTo(object l)
    {
        return GetHashCode() - l.GetHashCode();
    }
}

2 个答案:

答案 0 :(得分:1)

好吧,您说过您不想要私有构造函数,但是如果您拥有公共静态属性,例如以下内容,该怎么办?

public class Lane
{
    private Direction direction;
    private int number;

    public static Lane L1 = new Lane(Direction.INCREASING, 1);
    public static Lane L2 = new Lane(Direction.INCREASING, 2);
    //add more ...

    private Lane() { }

    private Lane(Direction d, int n)
    {
        this.direction = d;
        this.number = n;
    }

    public enum Direction
    {
        INCREASING = 1, DECREASING = 2, BOTH = 3, OTHER = 4, UNSPECIFIED = 5
    }
}

这样,您可以键入lane = Lane.L1,并且它总是返回相同的实例。 这够了吗?

答案 1 :(得分:1)

您不能用enum做您想做的事,因为这听起来好像您没有对“数字”部分进行限制,并且您无法在运行时定义或使用新的枚举

这可能就是您所需要的:

public static class Lanes
{ 
    private static readonly Dictionary<string, Lane> LanesDictionary = 
        new Dictionary<string, Lane>();

    public static Lane GetLane(Direction direction, int number)
    {
        var key = direction.ToString() + number;
        if (LanesDictionary.ContainsKey(key))
        {
            return LanesDictionary[key];
        }
        var lane = new Lane(direction, number);
        LanesDictionary.Add(key, lane);
        return lane;
    }
}

现在,每次引用Lanes.GetLane(Direction.INCREASING, 4)时,您总是会得到相同的Lane。如果尚不存在,则会创建它。

这为您提供了方便,易读的方式来引用给定车道。如果出于某种原因您想要某些车道的简写-尽管如上所述,您不想对其进行硬编码(我也不会),您可以这样做:

public static Lane L4 { get; } = GetLane(Direction.INCREASING, 4);