首页 > 解决方案 > 本质上是一个二维枚举?

问题描述

不知道如何表达这个,但我有一个名为 Lane 的课程,用于道路的不同车道。

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

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

正因为如此,我希望能够以分配枚举的方式分配对象的 Lane,通过键入 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();
    }
}

标签: c#software-design

解决方案


你不能用 an 做你想做的事,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);

推荐阅读