C#枚举的替代方法以获得智能优势

时间:2019-01-02 12:41:19

标签: c#

我有一个基类

abstract public class ComponentBase
{
    public List<string> Actions { get; set; }

    protected abstract void RegisterActions();
}

及其子代

public class VideoBase : ComponentBase
{
    protected override void RegisterActions()
    {
        base.Actions.Add("Start video");
        base.Actions.Add("Pause video");
        base.Actions.Add("Rewind video");
    }
}

但是为了使事情变得更容易,我还创建了枚举类型

public enum Actions
{
    START_VIDEO,
    PAUSE_VIDEO,
    REWIND_VIDEO,
}

我想要的是强制ComponentBase的每个子级都有其自己的枚举Actions,但这似乎并不容易。另外,尽管我将将“动作列表”更改为Dictionary<string, string>,但这并没有给我带来智能优势。我希望此类用户可以很容易地在智能感知中获得动作的“列表”,而不是检查他们必须输入的字符串值,有什么建议吗?

2 个答案:

答案 0 :(得分:5)

在基类中使用泛型怎么样?

abstract public class ComponentBase<T> where T : struct
{
    //Example property.
    public T Action { get; set; }
}
  

正如InBetween所述,在C#7.3中,您可以添加一个附加约束来强制将泛型类型作为枚举:

abstract public class ComponentBase<T> where T : struct, System.Enum

通过这种方式,您可以指定在子类中继承ComponentBase时要使用的枚举:

public class VideoBase : ComponentBase<VideoActions>
{
    ...your code...
}

public enum VideoActions
{
    START_VIDEO,
    PAUSE_VIDEO,
    REWIND_VIDEO
}
VideoBase video = new VideoBase();

//video.Action will now be of type VideoActions.
video.Action = VideoActions.START_VIDEO;

答案 1 :(得分:3)

如果您想使用类似enum的实现来将值限制为字符串值的特定子集,则有一个解决方案。您可以使用私有构造函数和静态字段创建一个类:

public class Action
{
    /// <summary>
    /// Start video
    /// </summary>
    public static readonly Action START_VIDEO = new Action("Start video");

    /// <summary>
    /// Pause video
    /// </summary>
    public static readonly Action PAUSE_VIDEO = new Action("Pause video");

    /// <summary>
    /// Rewind video
    /// </summary>
    public static readonly Action REWIND_VIDEO = new Action("Rewind video");


    private readonly string _value;

    private Action(string value)
    {
        _value = value;
    }

    public override string ToString()
    {
        return _value;
    }

    public static implicit operator string(Action action)
    {
        return action._value;
    }
}

每当您将任何输入限制为Action时,例如您的列表

public List<Action> Actions { get; set; }

或类似的

public void RegisterAction(Action action) { }

这会将值限制为Action类中声明的值之一,而不是允许使用任何string

然后您可以进行Actions.Add(<intellisense suggestions show up>) enter image description here

,并在需要时仍将其用作代码中的string

// Implicit conversion
string someValue = Action.START_VIDEO;

// .ToString() override
Console.WriteLine("Action: " + Action.START_VIDEO);

在两种情况下,代码都将使用在类中声明的字符串表示形式,而不是使用enum情况下的名称。

此外,通过在<summary>中提供描述,您还可以获得在将鼠标悬停在对Action的引用上时看到实际值的优点。