jim*_*jim 1698 c# int enums casting
我有一个叫Questions(复数)的类.在这个类中有一个名为Question(单数)的枚举,看起来像这样.
public enum Question
{
Role = 2,
ProjectFunding = 3,
TotalEmployee = 4,
NumberOfServers = 5,
TopBusinessConcern = 6
}
Run Code Online (Sandbox Code Playgroud)
在Questions类中,我有一个get(int foo)函数返回一个Questions对象foo.有没有一种简单的方法从枚举中获取整数值,所以我可以做类似的事情Questions.Get(Question.Role)?
Tet*_*ron 2206
刚刚施放枚举,例如
int something = (int) Question.Role;
Run Code Online (Sandbox Code Playgroud)
以上内容适用于您在野外看到的绝大多数枚举,因为枚举的默认基础类型是int.
但是,正如cecilphillip指出的那样,枚举可以有不同的底层类型.如果枚举被声明为uint,long,或ulong,应当投射到枚举的类型; 例如
enum StarsInMilkyWay:long {Sun = 1, V645Centauri = 2 .. Wolf424B = 2147483649};
Run Code Online (Sandbox Code Playgroud)
你应该使用
long something = (long)StarsInMilkyWay.Wolf424B;
Run Code Online (Sandbox Code Playgroud)
cec*_*lip 291
由于枚举可以是任何整数类型(byte,int,short等),更鲁棒的方式来获得的枚举的基本积分值将是使使用的GetTypeCode方法与结合Convert类:
enum Sides {
Left, Right, Top, Bottom
}
Sides side = Sides.Bottom;
object val = Convert.ChangeType(side, side.GetTypeCode());
Console.WriteLine(val);
Run Code Online (Sandbox Code Playgroud)
无论底层整数类型如何,这都应该有效.
小智 189
将其声明为具有公共常量的静态类:
public static class Question
{
public const int Role = 2;
public const int ProjectFunding = 3;
public const int TotalEmployee = 4;
public const int NumberOfServers = 5;
public const int TopBusinessConcern = 6;
}
Run Code Online (Sandbox Code Playgroud)
然后你可以引用它Question.Role,并且它总是评估为int或者你定义它的任何东西.
jer*_*jvl 83
Question question = Question.Role;
int value = (int) question;
Run Code Online (Sandbox Code Playgroud)
会导致value == 2.
naw*_*fal 77
在相关的说明中,如果您想从中获取int值System.Enum,则e在此处给出:
Enum e = Question.Role;
Run Code Online (Sandbox Code Playgroud)
您可以使用:
int i = Convert.ToInt32(e);
int i = (int)(object)e;
int i = (int)Enum.Parse(e.GetType(), e.ToString());
int i = (int)Enum.ToObject(e.GetType(), e);
Run Code Online (Sandbox Code Playgroud)
最后两个是丑陋的.我更喜欢第一个.
Mic*_*tta 40
它比你想象的容易 - 枚举已经是一个整数.它只需要提醒:
int y = (int)Question.Role;
Console.WriteLine(y); // prints 2
Run Code Online (Sandbox Code Playgroud)
小智 32
例:
public Enum EmpNo
{
Raj = 1,
Rahul,
Priyanka
}
Run Code Online (Sandbox Code Playgroud)
并在后面的代码中获取枚举值:
int setempNo = (int)EmpNo.Raj; //This will give setempNo = 1
Run Code Online (Sandbox Code Playgroud)
要么
int setempNo = (int)EmpNo.Rahul; //This will give setempNo = 2
Run Code Online (Sandbox Code Playgroud)
枚举将增加1,您可以设置起始值.如果未设置起始值,则最初将其指定为0.
Joh*_*van 27
我最近在代码中转而使用枚举,转而使用带有受保护构造函数和预定义静态实例的类(感谢Roelof - C# Ensure Valid Enum Values - Futureproof Method).
鉴于此,下面是我现在如何解决这个问题(包括隐式转换为/来自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)
}
Run Code Online (Sandbox Code Playgroud)
这种方法的优点是你可以从枚举中获得所有内容,但是你的代码现在更加灵活,所以如果你需要根据值执行不同的操作Question,你可以将逻辑放入Question自身(即在首选的OO中)时尚)而不是在整个代码中放置大量的case语句来处理每个场景.
注意:答案更新2018-04-27以利用C#6功能; 即声明表达式和lambda表达式主体定义.查看原始代码的修订历史记录.这样做的好处是使定义不那么冗长; 这是对这个答案方法的主要抱怨之一.
小智 19
如果你想得到一个存储在一个变量中的枚举值的整数,那个类型就是Question,例如在一个方法中使用,你可以简单地这样做我在这个例子中写的:
enum Talen
{
Engels = 1, Italiaans = 2, Portugees = 3, Nederlands = 4, Duits = 5, Dens = 6
}
Talen Geselecteerd;
public void Form1()
{
InitializeComponent()
Geselecteerd = Talen.Nederlands;
}
// You can use the Enum type as a parameter, so any enumeration from any enumerator can be used as parameter
void VeranderenTitel(Enum e)
{
this.Text = Convert.ToInt32(e).ToString();
}
Run Code Online (Sandbox Code Playgroud)
这会将窗口标题更改为4,因为变量Geselecteerd是Talen.Nederlands.如果我将其更改为Talen.Portugees并再次调用该方法,则文本将更改为3.
我很难在互联网上找到这个简单的解决方案而我找不到它,所以我正在测试一些东西并发现了这一点.希望这可以帮助.;)
小智 15
要确保存在枚举值然后解析它,您还可以执行以下操作.
// Fake Day of Week
string strDOWFake = "SuperDay";
// Real Day of Week
string strDOWReal = "Friday";
// Will hold which ever is the real DOW.
DayOfWeek enmDOW;
// See if fake DOW is defined in the DayOfWeek enumeration.
if (Enum.IsDefined(typeof(DayOfWeek), strDOWFake))
{
// This will never be reached since "SuperDay"
// doesn't exist in the DayOfWeek enumeration.
enmDOW = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), strDOWFake);
}
// See if real DOW is defined in the DayOfWeek enumeration.
else if (Enum.IsDefined(typeof(DayOfWeek), strDOWReal))
{
// This will parse the string into it's corresponding DOW enum object.
enmDOW = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), strDOWReal);
}
// Can now use the DOW enum object.
Console.Write("Today is " + enmDOW.ToString() + ".");
Run Code Online (Sandbox Code Playgroud)
我希望这有帮助.
小智 14
也许我错过了它,但有人试过一个简单的通用扩展方法.这对我很有用.您可以通过这种方式避免API中的类型转换,但最终会导致更改类型操作.这是编程Roselyn以使编译器为您创建GetValue方法的好例子.
public static void Main()
{
int test = MyCSharpWrapperMethod(TestEnum.Test1);
Debug.Assert(test == 1);
}
public static int MyCSharpWrapperMethod(TestEnum customFlag)
{
return MyCPlusPlusMethod(customFlag.GetValue<int>());
}
public static int MyCPlusPlusMethod(int customFlag)
{
//Pretend you made a PInvoke or COM+ call to C++ method that require an integer
return customFlag;
}
public enum TestEnum
{
Test1 = 1,
Test2 = 2,
Test3 = 3
}
}
public static class EnumExtensions
{
public static T GetValue<T>(this Enum enumeration)
{
T result = default(T);
try
{
result = (T)Convert.ChangeType(enumeration, typeof(T));
}
catch (Exception ex)
{
Debug.Assert(false);
Debug.WriteLine(ex);
}
return result;
}
}
Run Code Online (Sandbox Code Playgroud)
pla*_*ont 13
还有一种方法:
Console.WriteLine("Name: {0}, Value: {0:D}", Question.Role);
Run Code Online (Sandbox Code Playgroud)
将导致:
Name: Role, Value: 2
Run Code Online (Sandbox Code Playgroud)
Kni*_*ins 12
public enum QuestionType
{
Role = 2,
ProjectFunding = 3,
TotalEmployee = 4,
NumberOfServers = 5,
TopBusinessConcern = 6
}
Run Code Online (Sandbox Code Playgroud)
......是一个很好的宣言.
你必须像这样将结果转换为int:
int Question = (int)QuestionType.Role
Run Code Online (Sandbox Code Playgroud)
否则,类型仍然是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
}
Run Code Online (Sandbox Code Playgroud)
声明它不太优雅,但你不需要在代码中强制转换它:
int Question = QuestionType.Role
Run Code Online (Sandbox Code Playgroud)
或者,您可能会对使用Visual Basic感到更舒服,因为Visual Basic可以满足许多领域的这种期望.
Bro*_*nek 10
您可以通过对定义的枚举类型实现扩展方法来执行此操作:
public static class MyExtensions
{
public static int getNumberValue(this Question questionThis)
{
return (int)questionThis;
}
}
Run Code Online (Sandbox Code Playgroud)
这简化了获取当前枚举值的int值:
Question question = Question.Role;
int value = question.getNumberValue();
Run Code Online (Sandbox Code Playgroud)
要么
int value = Question.Role.getNumberValue();
Run Code Online (Sandbox Code Playgroud)
小智 10
int number = Question.Role.GetHashCode();
Run Code Online (Sandbox Code Playgroud)
number应该有价值2.
用:
Question question = Question.Role;
int value = question.GetHashCode();
Run Code Online (Sandbox Code Playgroud)
它会导致value == 2.
仅当枚举适合int.
如何改为扩展方法:
public static class ExtensionMethods
{
public static int IntValue(this Enum argEnum)
{
return Convert.ToInt32(argEnum);
}
}
Run Code Online (Sandbox Code Playgroud)
而且用法稍微漂亮一些:
var intValue = Question.Role.IntValue();
Run Code Online (Sandbox Code Playgroud)
public enum Suit : int
{
Spades = 0,
Hearts = 1,
Clubs = 2,
Diamonds = 3
}
Console.WriteLine((int)(Suit)Enum.Parse(typeof(Suit), "Clubs"));
//from int
Console.WriteLine((Suit)1);
//From number you can also
Console.WriteLine((Suit)Enum.ToObject(typeof(Suit), 1));
if (typeof(Suit).IsEnumDefined("Spades"))
{
var res = (int)(Suit)Enum.Parse(typeof(Suit), "Spades");
Console.Out.WriteLine("{0}", res);
}
Run Code Online (Sandbox Code Playgroud)
我最喜欢的 int 或更小的枚举 hack:
GetHashCode();
Run Code Online (Sandbox Code Playgroud)
对于一个枚举
public enum Test
{
Min = Int32.MinValue,
One = 1,
Max = Int32.MaxValue,
}
Run Code Online (Sandbox Code Playgroud)
这,
var values = Enum.GetValues(typeof(Test));
foreach (var val in values)
{
Console.WriteLine(val.GetHashCode());
Console.WriteLine(((int)val));
Console.WriteLine(val);
}
Run Code Online (Sandbox Code Playgroud)
输出
one
1
1
max
2147483647
2147483647
min
-2147483648
-2147483648
Run Code Online (Sandbox Code Playgroud)
免责声明:
它不适用于基于 long 的枚举。
您应该使用类型转换,就像我们可以在任何其他语言中使用一样。
如果你enum是这样的——
public enum Question
{
Role = 2,
ProjectFunding = 3,
TotalEmployee = 4,
NumberOfServers = 5,
TopBusinessConcern = 6
}
Run Code Online (Sandbox Code Playgroud)
你需要转换为int,然后执行此操作 -
Question q = Question.Role;
.............
.............
int something = (int) q;
Run Code Online (Sandbox Code Playgroud)
在 C# 中,有两种类型的转换:
char->int->long->float->double
double->float->long->int->char
更多内容可以在这里找到。
我能想到的最简单的解决方案是重载该Get(int)方法,如下所示:
[modifiers] Questions Get(Question q)
{
return Get((int)q);
}
Run Code Online (Sandbox Code Playgroud)
其中[modifiers]通常可以与方法相同Get(int)。如果您无法编辑该类Questions或由于某种原因不想编辑该类,您可以通过编写扩展来重载该方法:
public static class Extensions
{
public static Questions Get(this Questions qs, Question q)
{
return qs.Get((int)q);
}
}
Run Code Online (Sandbox Code Playgroud)
我想建议“从枚举中获取‘int’值”的例子是
public enum Sample
{
Book = 1,
Pen = 2,
Pencil = 3
}
int answer = (int)Sample.Book;
Run Code Online (Sandbox Code Playgroud)
现在答案是1。
小智 5
由于可以用多种基本类型声明枚举,所以泛型转换任何枚举类型的通用扩展方法可能会很有用。
enum Box
{
HEIGHT,
WIDTH,
DEPTH
}
public static void UseEnum()
{
int height = Box.HEIGHT.GetEnumValue<int>();
int width = Box.WIDTH.GetEnumValue<int>();
int depth = Box.DEPTH.GetEnumValue<int>();
}
public static T GetEnumValue<T>(this object e) => (T)e;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1417161 次 |
| 最近记录: |