C# 将枚举转换为另一种类型的枚举
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1818131/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
convert an enum to another type of enum
提问by kurasa
I have an enum of for example 'Gender
' (Male =0 , Female =1
) and I have another enum from a service which has its own Gender enum (Male =0 , Female =1, Unknown =2
)
我有一个例如 ' Gender
' ( Male =0 , Female =1
) 的枚举,我有另一个来自具有自己的 Gender 枚举 ( Male =0 , Female =1, Unknown =2
)的服务的枚举
My question is how can I write something quick and nice to convert from their enum to mine?
我的问题是我怎样才能写出一些快速而漂亮的东西来从他们的枚举转换为我的枚举?
采纳答案by Zooba
Using an extension method works quite neatly, when using the two conversion methods suggested by Nate:
当使用 Nate 建议的两种转换方法时,使用扩展方法非常有效:
public static class TheirGenderExtensions
{
public static MyGender ToMyGender(this TheirGender value)
{
// insert switch statement here
}
}
public static class MyGenderExtensions
{
public static TheirGender ToTheirGender(this MyGender value)
{
// insert switch statement here
}
}
Obviously there's no need to use separate classes if you don't want to. My preference is to keep extension methods grouped by the classes/structures/enumerations they apply to.
显然,如果您不想,则无需使用单独的类。我的偏好是将扩展方法按它们适用的类/结构/枚举分组。
回答by Nate C-K
To be thorough I normally create a pair of functions, one that takes Enum 1 and returns Enum 2 and another that takes Enum 2 and returns Enum 1. Each consists of a case statement mapping inputs to outputs and the default case throws an exception with a message complaining about an unexpected value.
为了彻底,我通常创建一对函数,一个接受 Enum 1 并返回 Enum 2,另一个接受 Enum 2 并返回 Enum 1。每个都包含一个 case 语句,将输入映射到输出,并且默认 case 抛出一个异常抱怨意外值的消息。
In this particular case you could take advantage of the fact that the integer values of Male and Female are the same, but I'd avoid that as it's hackish and subject to breakage if either enum changes in the future.
在这种特殊情况下,您可以利用男性和女性的整数值相同的事实,但我会避免这种情况,因为如果将来任何一个枚举发生变化,它都是黑客行为并且可能会损坏。
回答by Marc Gravell
Given Enum1 value = ...
, then if you mean by name:
Given Enum1 value = ...
,那么如果您指的是名称:
Enum2 value2 = (Enum2) Enum.Parse(typeof(Enum2), value.ToString());
If you mean by numeric value, you can usually just cast:
如果你的意思是数值,你通常可以只转换:
Enum2 value2 = (Enum2)value;
(with the cast, you might want to use Enum.IsDefined
to check for valid values, though)
(不过,使用演员表,您可能想用它Enum.IsDefined
来检查有效值)
回答by Jason Williams
You can use ToString() to convert the first enum to its name, and then Enum.Parse() to convert the string back to the other Enum. This will throw an exception if the value is not supported by the destination enum (i.e. for an "Unknown" value)
您可以使用 ToString() 将第一个枚举转换为其名称,然后使用 Enum.Parse() 将字符串转换回另一个枚举。如果目标枚举不支持该值(即“未知”值),这将引发异常
回答by RCIX
you could write a simple function like the following:
你可以写一个简单的函数,如下所示:
public static MyGender ConvertTo(TheirGender theirGender)
{
switch(theirGender)
{
case TheirGender.Male:
break;//return male
case TheirGender.Female:
break;//return female
case TheirGender.Unknown:
break;//return whatever
}
}
回答by Adrian Zanescu
Just cast one to int and then cast it to the other enum (considering that you want the mapping done based on value):
只需将一个转换为 int,然后将其转换为另一个枚举(考虑到您希望根据值完成映射):
Gender2 gender2 = (Gender2)((int)gender1);
回答by Jishnu A P
You could write a simple generic extension method like this
您可以像这样编写一个简单的通用扩展方法
public static T ConvertTo<T>(this object value)
where T : struct,IConvertible
{
var sourceType = value.GetType();
if (!sourceType.IsEnum)
throw new ArgumentException("Source type is not enum");
if (!typeof(T).IsEnum)
throw new ArgumentException("Destination type is not enum");
return (T)Enum.Parse(typeof(T), value.ToString());
}
回答by Thick_propheT
I wrote a set extension methods a while back that work for several different kinds of Enum
s. One in particular works for what you are trying to accomplish and handles Enum
s with the FlagsAttribute
as well as Enum
s with different underlying types.
不久前我写了一套扩展方法,适用于几种不同类型的Enum
s。一种特别适用于您要完成的工作,并使用Enum
sFlagsAttribute
以及Enum
具有不同底层类型的 s来处理。
public static tEnum SetFlags<tEnum>(this Enum e, tEnum flags, bool set, bool typeCheck = true) where tEnum : IComparable
{
if (typeCheck)
{
if (e.GetType() != flags.GetType())
throw new ArgumentException("Argument is not the same type as this instance.", "flags");
}
var flagsUnderlyingType = Enum.GetUnderlyingType(typeof(tEnum));
var firstNum = Convert.ToUInt32(e);
var secondNum = Convert.ToUInt32(flags);
if (set)
firstNum |= secondNum;
else
firstNum &= ~secondNum;
var newValue = (tEnum)Convert.ChangeType(firstNum, flagsUnderlyingType);
if (!typeCheck)
{
var values = Enum.GetValues(typeof(tEnum));
var lastValue = (tEnum)values.GetValue(values.Length - 1);
if (newValue.CompareTo(lastValue) > 0)
return lastValue;
}
return newValue;
}
From there you can add other more specific extension methods.
从那里您可以添加其他更具体的扩展方法。
public static tEnum AddFlags<tEnum>(this Enum e, tEnum flags) where tEnum : IComparable
{
SetFlags(e, flags, true);
}
public static tEnum RemoveFlags<tEnum>(this Enum e, tEnum flags) where tEnum : IComparable
{
SetFlags(e, flags, false);
}
This one will change types of Enum
s like you are trying to do.
这将Enum
像您尝试做的那样改变s 的类型。
public static tEnum ChangeType<tEnum>(this Enum e) where tEnum : IComparable
{
return SetFlags(e, default(tEnum), true, false);
}
Be warned, though, that you CAN convert between any Enum
and any other Enum
using this method, even those that do not have flags. For example:
但是请注意,您可以使用此方法在任何Enum
和任何其他之间进行转换Enum
,即使是那些没有标志的。例如:
public enum Turtle
{
None = 0,
Pink,
Green,
Blue,
Black,
Yellow
}
[Flags]
public enum WriteAccess : short
{
None = 0,
Read = 1,
Write = 2,
ReadWrite = 3
}
static void Main(string[] args)
{
WriteAccess access = WriteAccess.ReadWrite;
Turtle turtle = access.ChangeType<Turtle>();
}
The variable turtle
will have a value of Turtle.Blue
.
该变量turtle
的值为Turtle.Blue
。
However, there is safety from undefined Enum
values using this method. For instance:
但是,Enum
使用此方法可以避免未定义的值。例如:
static void Main(string[] args)
{
Turtle turtle = Turtle.Yellow;
WriteAccess access = turtle.ChangeType<WriteAccess>();
}
In this case, access
will be set to WriteAccess.ReadWrite
, since the WriteAccess
Enum
has a maximum value of 3.
在这种情况下,access
将设置为WriteAccess.ReadWrite
,因为 的WriteAccess
Enum
最大值为 3。
Another side effect of mixing Enum
s with the FlagsAttribute
and those without it is that the conversion process will not result in a 1 to 1 match between their values.
将Enum
s 与 sFlagsAttribute
和不带s混合的另一个副作用是转换过程不会导致它们的值之间 1 比 1 匹配。
public enum Letters
{
None = 0,
A,
B,
C,
D,
E,
F,
G,
H
}
[Flags]
public enum Flavors
{
None = 0,
Cherry = 1,
Grape = 2,
Orange = 4,
Peach = 8
}
static void Main(string[] args)
{
Flavors flavors = Flavors.Peach;
Letters letters = flavors.ChangeType<Letters>();
}
In this case, letters
will have a value of Letters.H
instead of Letters.D
, since the backing value of Flavors.Peach
is 8. Also, a conversion from Flavors.Cherry | Flavors.Grape
to Letters
would yield Letters.C
, which can seem unintuitive.
在这种情况下,letters
将有一个值Letters.H
而不是Letters.D
,因为 的支持值Flavors.Peach
是 8。此外,从Flavors.Cherry | Flavors.Grape
到的转换Letters
会产生Letters.C
,这似乎不直观。
回答by Justin
Here's an extension method version if anyone is interested
如果有人感兴趣,这是一个扩展方法版本
public static TEnum ConvertEnum<TEnum >(this Enum source)
{
return (TEnum)Enum.Parse(typeof(TEnum), source.ToString(), true);
}
// Usage
NewEnumType newEnum = oldEnumVar.ConvertEnum<NewEnumType>();
回答by Nedcode
If we have:
如果我们有:
enum Gender
{
M = 0,
F = 1,
U = 2
}
and
和
enum Gender2
{
Male = 0,
Female = 1,
Unknown = 2
}
We can safely do
我们可以安全地做
var gender = Gender.M;
var gender2 = (Gender2)(int)gender;
Or even
甚至
var enumOfGender2Type = (Gender2)0;
If you want to cover the case where an enum on the right side of the '=' sign has more values than the enum on the left side - you will have to write your own method/dictionary to cover that as others suggested.
如果您想涵盖“=”符号右侧的枚举比左侧的枚举具有更多值的情况 - 您将必须编写自己的方法/字典来涵盖其他人的建议。