强制一个类实现一个没有值约束的枚举

时间:2017-10-29 10:53:17

标签: c# class enums interface

我有不同的类别(例如:玩家,敌人,小行星......) - 它们应该具有不同的状态(例如:ok,传送......)。

enum Status
{
    Ok,
    Teleporting,
    ...
};

使用界面,我想强制这些类在其中声明枚举状态变量的仅存在。但是,我希望没有值限制。也就是说,玩家和敌人可以在内部状态中具有不同的值(例如:一个可以传送,另一个可以' t)。

我该怎么做?

UPDATE1

public enum Status
{
    Ok,
    Teleporting
};

public interface IHaveStatus
{
    Status Status { get; set; }
}

更新2

public enum Status
{
    Ok,
    Teleporting
};

public interface IHaveStatus
{
    Status status;
}

4 个答案:

答案 0 :(得分:1)

您可以按如下方式声明接口:

public interface IHaveStatus {
    Status Status { get; set; }
}

让特定的类实现该接口:

class Player: IHaveStatus {
    public Status Status { get; set; }
}

这不会限制状态字段的使用,它可以包含Status枚举合法的任何值。

如果(但是)你想要应用一些逻辑(敌人不能传送),那么这可能不是正确的设计。

如果您想指定玩家具有某些能力(即:传送),您可以使用属性或界面来识别这些类别。

使用界面:

public interface ICanTeleport { }

public class Player : ICanTeleport { ... }

您可以使用演员来确定能力:

if(somePlayer is ICanTeleport) { .. }

或使用attributes时:

[System.AttributeUsage(System.AttributeTargets.Class)]  
public class Teleporter : System.Attribute  
{ }

[Teleporter()]
public class Player { ... }

然后您必须使用反射来确定属性,请参阅this question

  • 使用接口可以将行为绑定到类继承。它还为您提供了向界面添加方法的能力(即Teleport(coordinates)方法)。

  • 使用属性可以动态地混合和匹配功能,因为没有类层次结构可以强制实现。

答案 1 :(得分:1)

除非我遗漏了一些明显的东西,否则像这样的简单界面就会这样做:

 public interface IHaveStatus
 {
      Status Status {get;}
 }

我将放在具体类中的值约束。例如,如果一名球员无法传送,那么这是一个限制属性的好地方:

public class Player : IHaveStatus
{
    private Status _status;

    public Status Status 
    {
        get {return _status;}
        set
        {
            // a player can't teleport...
            if(value != Status.Teleport)
            {
                _status = value;
            }
        }
    }
}

答案 2 :(得分:1)

你不能,至少不能使用相同的枚举类型。您必须为每组允许值声明不同的枚举。 Pro:您将获得编译时检查(只要您通常使用Enums值显式指定值)。 Con:你必须为每个允许的范围声明一个新的枚举。

或者,您可以在setter(方法或属性)中的类型级别检查运行时的传入值,并在那里强制执行任何约束。亲:您只需要一个整数范围的枚举。 Con:这个解决方案的缺点是你可能会遇到在运行时才会遇到的错误。

每个可接受范围的解决方案枚举

enum EnemyStatus
{
    Ok
}

enum UserStatus
{
    Ok,
    Teleporting
}

类型级别的解决方案约束

class Enemy : IStatusable {

  public Status CurrentStatus {
    get {return _status;}
    set {if(value == Status.Teleporting) throw new NotSupportedException();
         this._status = value;
    }}
}

interface IStatusable {
   Status CurrentStatus {get;set;}
}

答案 3 :(得分:1)

如果枚举标有[Flags]属性,则可以在单个枚举字段中组合多个值:

[Flags]
enum Status
{
    Ok = 0,
    Teleporting = 1,
    Flying = 2,
    Dancing = 4
}

然后使用一个枚举属性声明接口:

interface Base
{
    Status Abilities { get; }
}

class Player : Base
{
    public Status Abilities { get; set; }
}

并测试对象的不同值,如下所示:

var p = new Player();
p.Abilities = Status.Ok | Status.Teleporting;

bool canTeleport = p.Abilities.HasFlag(Status.Teleporting);
bool canFly = p.Abilities.HasFlag(Status.Flying);