这里有更多面向对象的方式来实现您想要实现的目标。该解决方案受到早期 Java 枚举方法的启发:
struct Sport {
readonly int value;
public Sport(int value) {
this.value = value;
}
public static implicit operator int(Sport sport) {
return sport.value;
}
public static implicit operator Sport(int sport) {
return new Sport(sport);
}
public const int Tennis = 0;
public const int Football = 1;
public const int Squash = 2;
public const int Volleyball = 3;
}
//Usage:
Sport sport = Sport.Volleyball;
switch(sport) {
case Sport.Squash:
Console.WriteLine("I bounce really high");
break;
}
Sport rugby = 5;
if (sport == rugby)
Console.WriteLine("I am really big and eat a lot");
了解此解决方案的不同功能。
它是一个不可变结构,包含一个整数值。 readonly 关键字强制该值不可变。
创建这些结构之一的唯一方法是调用将值作为参数的构造函数。
implicit operator int 在那里,因此可以在 switch 块中使用该结构 - 即使该结构可转换为 int。
implicit operator Sport 在那里,您可以将整数值分配给结构,即Sport rugby = 5。
const 值是编译时已知的运动。它们也可以用作case 标签。
我实际上会做什么
public static class Sports {
public static readonly Sport Football = new Sport("Football");
public static readonly Sport Tennis = new Sport("Tennis");
}
public class Sport {
public Sport(string name) {
Name = name;
}
public string Name { get; private set; }
// override object.Equals
public override bool Equals(object obj) {
var other = obj as Sport;
if(other == null) {
return false;
}
return other == this;
}
// override object.GetHashCode
public override int GetHashCode() {
return Name.GetHashCode();
}
public static bool operator == (Sport sport1, Sport sport2) {
if(Object.ReferenceEquals(sport1, null) && Object.ReferenceEquals(sport2 , null))
return true;
if(Object.ReferenceEquals(sport1, null) || Object.ReferenceEquals(sport2, null))
return false;
return sport1.Name == sport2.Name;
}
public static bool operator !=(Sport sport1, Sport sport2) {
return !(sport1 == sport2);
}
}
这将创建一个具有名称的值类Sport。根据您的应用程序,您可以扩展此类以提供其他属性和方法。将此作为类为您提供更大的灵活性,因为您可以将其子类化。
Sports 类提供了在编译时已知的静态运动集合。这类似于某些 .NET 框架处理命名颜色(即 WPF)的方式。用法如下:
List<Sport> sports = new List<Sport>();
sports.Add(Sports.Football);
sports.Add(Sports.Tennis);
//What if the name contains spaces?
sports.Add(new Sport("Water Polo"));
var otherSport = new Sport("Other sport");
if(sports.Contains(otherSport)) {
//Do something
}
foreach(var sport in sports) {
if(sport == otherSport) {
//Do Something
} else if(sport == Sports.Football) {
//do something else
}
}
完成此操作后,您会发现实际上几乎不需要枚举,因为运动类型的任何条件操作都可以在 Sport 类中处理。
编辑意识到我的相等运算符会抛出一个StackOverflowException 我总是忘记写Object.ReferenceEquals(obj,null) 而不是obj==null,这将无限递归。