我有不同的类别(例如:玩家,敌人,小行星......) - 它们应该具有不同的状态(例如:ok,传送......)。
enum Status
{
Ok,
Teleporting,
...
};
使用界面,我想强制这些类在其中声明枚举状态变量的仅存在。但是,我希望没有值限制。也就是说,玩家和敌人可以在内部状态中具有不同的值(例如:一个可以传送,另一个可以' t)。
我该怎么做?
public enum Status
{
Ok,
Teleporting
};
public interface IHaveStatus
{
Status Status { get; set; }
}
public enum Status
{
Ok,
Teleporting
};
public interface IHaveStatus
{
Status status;
}
答案 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);