我有一门课叫问题(复数)。在这个类中有一个名为Question(单数)的枚举,看起来像这样。
public enum Question
{
Role = 2,
ProjectFunding = 3,
TotalEmployee = 4,
NumberOfServers = 5,
TopBusinessConcern = 6
}
在Questions类中,我有一个get(intfoo)函数,它为该foo返回Questions对象。有没有一种简单的方法可以从枚举中获取整数值,这样我就可以执行类似于Questions.get(Questions.Role)的操作?
最近,我不再在代码中使用枚举,而是使用带有受保护构造函数和预定义静态实例的类(感谢Roelof-C#确保有效枚举值-Futureproof方法)。
鉴于此,下面是我现在如何处理这个问题(包括隐式转换为int或从int转换)。
public class Question
{
// Attributes
protected int index;
protected string name;
// Go with a dictionary to enforce unique index
//protected static readonly ICollection<Question> values = new Collection<Question>();
protected static readonly IDictionary<int,Question> values = new Dictionary<int,Question>();
// Define the "enum" values
public static readonly Question Role = new Question(2,"Role");
public static readonly Question ProjectFunding = new Question(3, "Project Funding");
public static readonly Question TotalEmployee = new Question(4, "Total Employee");
public static readonly Question NumberOfServers = new Question(5, "Number of Servers");
public static readonly Question TopBusinessConcern = new Question(6, "Top Business Concern");
// Constructors
protected Question(int index, string name)
{
this.index = index;
this.name = name;
values.Add(index, this);
}
// Easy int conversion
public static implicit operator int(Question question) =>
question.index; //nb: if question is null this will return a null pointer exception
public static implicit operator Question(int index) =>
values.TryGetValue(index, out var question) ? question : null;
// Easy string conversion (also update ToString for the same effect)
public override string ToString() =>
this.name;
public static implicit operator string(Question question) =>
question?.ToString();
public static implicit operator Question(string name) =>
name == null ? null : values.Values.FirstOrDefault(item => name.Equals(item.name, StringComparison.CurrentCultureIgnoreCase));
// If you specifically want a Get(int x) function (though not required given the implicit converstion)
public Question Get(int foo) =>
foo; //(implicit conversion will take care of the conversion for you)
}
这种方法的优点是你可以从枚举中得到所有的东西,但是你的代码现在更灵活了,所以如果你需要根据Question的值执行不同的操作,你可以将逻辑放入Question本身(即以首选的OO方式),而不是在代码中放入大量的case语句来处理每个场景。
注意:2018-04-27更新了答案,以利用C#6功能;即声明表达式和lambda表达式体定义。原始代码参见修订历史。这样做的好处是使定义不那么冗长;这是对这个答案方法的主要抱怨之一。
只需转换枚举,例如。
int something = (int) Question.Role;
以上内容适用于您在野外看到的绝大多数枚举,因为枚举的默认基础类型是int。
然而,正如cecilphilip所指出的,遗尿症可能有不同的潜在类型。如果枚举声明为uint、long或ulong,则应将其强制转换为枚举的类型;例如,用于
enum StarsInMilkyWay:long {Sun = 1, V645Centauri = 2 .. Wolf424B = 2147483649};
你应该使用
long something = (long)StarsInMilkyWay.Wolf424B;
public enum QuestionType
{
Role = 2,
ProjectFunding = 3,
TotalEmployee = 4,
NumberOfServers = 5,
TopBusinessConcern = 6
}
…是一个很好的声明。
您必须将结果强制转换为int,如下所示:
int Question = (int)QuestionType.Role
否则,类型仍然是QuestionType。
这种严格程度是C#的方式。
一种替代方法是改用类声明:
public class QuestionType
{
public static int Role = 2,
public static int ProjectFunding = 3,
public static int TotalEmployee = 4,
public static int NumberOfServers = 5,
public static int TopBusinessConcern = 6
}
声明不那么优雅,但不需要将其转换为代码:
int Question = QuestionType.Role
或者,您可能会对Visual Basic感到更舒服,它在许多方面都满足了这种期望。
最近,我不再在代码中使用枚举,而是使用带有受保护构造函数和预定义静态实例的类(感谢Roelof-C#确保有效枚举值-Futureproof方法)。
鉴于此,下面是我现在如何处理这个问题(包括隐式转换为int或从int转换)。
public class Question
{
// Attributes
protected int index;
protected string name;
// Go with a dictionary to enforce unique index
//protected static readonly ICollection<Question> values = new Collection<Question>();
protected static readonly IDictionary<int,Question> values = new Dictionary<int,Question>();
// Define the "enum" values
public static readonly Question Role = new Question(2,"Role");
public static readonly Question ProjectFunding = new Question(3, "Project Funding");
public static readonly Question TotalEmployee = new Question(4, "Total Employee");
public static readonly Question NumberOfServers = new Question(5, "Number of Servers");
public static readonly Question TopBusinessConcern = new Question(6, "Top Business Concern");
// Constructors
protected Question(int index, string name)
{
this.index = index;
this.name = name;
values.Add(index, this);
}
// Easy int conversion
public static implicit operator int(Question question) =>
question.index; //nb: if question is null this will return a null pointer exception
public static implicit operator Question(int index) =>
values.TryGetValue(index, out var question) ? question : null;
// Easy string conversion (also update ToString for the same effect)
public override string ToString() =>
this.name;
public static implicit operator string(Question question) =>
question?.ToString();
public static implicit operator Question(string name) =>
name == null ? null : values.Values.FirstOrDefault(item => name.Equals(item.name, StringComparison.CurrentCultureIgnoreCase));
// If you specifically want a Get(int x) function (though not required given the implicit converstion)
public Question Get(int foo) =>
foo; //(implicit conversion will take care of the conversion for you)
}
这种方法的优点是你可以从枚举中得到所有的东西,但是你的代码现在更灵活了,所以如果你需要根据Question的值执行不同的操作,你可以将逻辑放入Question本身(即以首选的OO方式),而不是在代码中放入大量的case语句来处理每个场景。
注意:2018-04-27更新了答案,以利用C#6功能;即声明表达式和lambda表达式体定义。原始代码参见修订历史。这样做的好处是使定义不那么冗长;这是对这个答案方法的主要抱怨之一。