Hoe kan een int
worden gecast naar een Enum
in C#?
Antwoord 1, autoriteit 100%
Van een int:
YourEnum foo = (YourEnum)yourInt;
Van een string:
YourEnum foo = (YourEnum) Enum.Parse(typeof(YourEnum), yourString);
// The foo.ToString().Contains(",") check is necessary for enumerations marked with an [Flags] attribute
if (!Enum.IsDefined(typeof(YourEnum), foo) && !foo.ToString().Contains(","))
{
throw new InvalidOperationException($"{yourString} is not an underlying value of the YourEnum enumeration.")
}
Bijwerken:
Vanaf nummer kunt u ook
YourEnum foo = (YourEnum)Enum.ToObject(typeof(YourEnum) , yourInt);
Antwoord 2, autoriteit 24%
Gewoon casten:
MyEnum e = (MyEnum)3;
Je kunt controleren of het binnen bereik is met Enum.IsDefined:
if (Enum.IsDefined(typeof(MyEnum), 3)) { ... }
Antwoord 3, autoriteit 6%
U kunt ook een uitbreidingsmethode gebruiken in plaats van een oneliner:
public static T ToEnum<T>(this string enumString)
{
return (T) Enum.Parse(typeof (T), enumString);
}
Gebruik:
Color colorEnum = "Red".ToEnum<Color>();
OF
string color = "Red";
var colorEnum = color.ToEnum<Color>();
Antwoord 4, autoriteit 5%
Ik denk dat om een volledig antwoord te krijgen, mensen moeten weten hoe opsommingen intern werken in .NET.
Hoe dingen werken
Een opsomming in .NET is een structuur die een set waarden (velden) toewijst aan een basistype (de standaard is int
). U kunt echter het integrale type kiezen waarnaar uw opsomming verwijst:
public enum Foo : short
In dit geval wordt de enum toegewezen aan het gegevenstype short
, wat betekent dat het als een short in het geheugen wordt opgeslagen en zich als een short gedraagt wanneer u deze cast en gebruikt.
Als je het vanuit een IL-oogpunt bekijkt, ziet een (normale, int) opsomming er als volgt uit:
.class public auto ansi serializable sealed BarFlag extends System.Enum
{
.custom instance void System.FlagsAttribute::.ctor()
.custom instance void ComVisibleAttribute::.ctor(bool) = { bool(true) }
.field public static literal valuetype BarFlag AllFlags = int32(0x3fff)
.field public static literal valuetype BarFlag Foo1 = int32(1)
.field public static literal valuetype BarFlag Foo2 = int32(0x2000)
// and so on for all flags or enum values
.field public specialname rtspecialname int32 value__
}
Wat moet u hier uw aandacht krijgen, is dat de value__
afzonderlijk van de ENUM-waarden wordt opgeslagen. In het geval van de ENUM Foo
hierboven, is het type value__
INT16. Dit betekent in feite dat u kunt opslaan wat u wilt in een ENUM, zolang de types overeenkomen met .
Op dit punt wil ik erop wijzen dat System.Enum
een waardetype is, wat in feite betekent dat BarFlag
4 bytes in het geheugen in beslag neemt en Foo
neemt 2 – bijv. de grootte van het onderliggende type (het is eigenlijk gecompliceerder dan dat, maar hey …).
het antwoord
Dus, als u een geheel getal hebt dat u naar een ENUM wilt plaatsen, hoeft de runtime slechts 2 dingen te doen: kopieer de 4 bytes en noem het iets anders (de naam van de ENUM). Het kopiëren is impliciet omdat de gegevens worden opgeslagen als waardetype – dit betekent in feite dat als u een onbeheerde code gebruikt, u eenvoudig en gehele getallen kunt uitwisselen zonder gegevens te kopiëren.
Om het veilig te maken, denk ik dat het een beste praktijk is voor weet dat de onderliggende typen hetzelfde zijn of impliciet converteerbaar zijn en om ervoor te zorgen dat de ENUM-waarden bestaan (ze worden niet standaard gecontroleerd!) .
Om te zien hoe dit werkt, probeer dan de volgende code:
public enum MyEnum : int
{
Foo = 1,
Bar = 2,
Mek = 5
}
static void Main(string[] args)
{
var e1 = (MyEnum)5;
var e2 = (MyEnum)6;
Console.WriteLine("{0} {1}", e1, e2);
Console.ReadLine();
}
Merk op dat het gieten naar e2
ook werkt! Vanuit het compilerperspectief hierboven is dit logisch: de value__
Veld is eenvoudig gevuld met 5 of 6 en wanneer Console.WriteLine
oproepen ToString()
, de naam van e1
is opgelost terwijl de naam e2
niet is.
Als dat niet is wat u van plan was, gebruikt u Enum.IsDefined(typeof(MyEnum), 6)
om te controleren of de waarde die u kaarten uitwerkt naar een gedefinieerd ENUM.
Merk ook op dat ik expliciet ben over het onderliggende type van de ENUM, ook al controleert de compiler dit daadwerkelijk. Ik doe dit om ervoor te zorgen dat ik geen verrassingen tegen de weg tegenkomt. Om deze verrassingen in actie te zien, kunt u de volgende code gebruiken (eigenlijk heb ik dit veel gezien in de databasecode):
public enum MyEnum : short
{
Mek = 5
}
static void Main(string[] args)
{
var e1 = (MyEnum)32769; // will not compile, out of bounds for a short
object o = 5;
var e2 = (MyEnum)o; // will throw at runtime, because o is of type int
Console.WriteLine("{0} {1}", e1, e2);
Console.ReadLine();
}
Antwoord 5, Autoriteit 3%
Neem het volgende voorbeeld:
int one = 1;
MyEnum e = (MyEnum)one;
Antwoord 6, Autoriteit 2%
Ik gebruik dit stuk code om int naar mijn ENUM te werpen:
if (typeof(YourEnum).IsEnumDefined(valueToCast)) return (YourEnum)valueToCast;
else { //handle it here, if its not defined }
Ik vind het de beste oplossing.
Antwoord 7
Hieronder is een leuke hulpprogramma voor ENUMS
public static class EnumHelper
{
public static int[] ToIntArray<T>(T[] value)
{
int[] result = new int[value.Length];
for (int i = 0; i < value.Length; i++)
result[i] = Convert.ToInt32(value[i]);
return result;
}
public static T[] FromIntArray<T>(int[] value)
{
T[] result = new T[value.Length];
for (int i = 0; i < value.Length; i++)
result[i] = (T)Enum.ToObject(typeof(T),value[i]);
return result;
}
internal static T Parse<T>(string value, T defaultValue)
{
if (Enum.IsDefined(typeof(T), value))
return (T) Enum.Parse(typeof (T), value);
int num;
if(int.TryParse(value,out num))
{
if (Enum.IsDefined(typeof(T), num))
return (T)Enum.ToObject(typeof(T), num);
}
return defaultValue;
}
}
Antwoord 8
Voor numerieke waarden is dit veiliger omdat het een object retourneert, wat er ook gebeurt:
public static class EnumEx
{
static public bool TryConvert<T>(int value, out T result)
{
result = default(T);
bool success = Enum.IsDefined(typeof(T), value);
if (success)
{
result = (T)Enum.ToObject(typeof(T), value);
}
return success;
}
}
Antwoord 9
Als je klaar bent voor het 4.0 .NETFramework, is er een nieuw Enum.TryParse( )functie die erg handig is en goed samengaat met het [Flags] attribuut. Zie Enum.TryParse-methode (String, TEnum%)
Antwoord 10
Als u een geheel getal hebt dat fungeert als een bitmask en kan u een of meer waarden in een [vlaggen] -opname voorstellen, kunt u deze code gebruiken om de individuele vlagwaarden in een lijst te volgen:
for (var flagIterator = 0; flagIterator < 32; flagIterator++)
{
// Determine the bit value (1,2,4,...,Int32.MinValue)
int bitValue = 1 << flagIterator;
// Check to see if the current flag exists in the bit mask
if ((intValue & bitValue) != 0)
{
// If the current flag exists in the enumeration, then we can add that value to the list
// if the enumeration has that flag defined
if (Enum.IsDefined(typeof(MyEnum), bitValue))
Console.WriteLine((MyEnum)bitValue);
}
}
Merk op dat dit ervan uitgaande dat het onderliggende type van de Enum
een ondertekend 32-bits geheel getal is. Als het een ander numeriek type wist, zou u de hardcoded 32 moeten wijzigen om de bits in dat type (of programmatisch af te leiden met behulp van Enum.GetUnderlyingType()
)
Antwoord 11
Soms heb je een object op de MyEnum
Type. Zoals
var MyEnumType = typeof(MyEnum);
Dan:
Enum.ToObject(typeof(MyEnum), 3)
Antwoord 12
Dit is een vlaggenvernieuwing bewust Safe Convert-methode:
public static bool TryConvertToEnum<T>(this int instance, out T result)
where T: Enum
{
var enumType = typeof (T);
var success = Enum.IsDefined(enumType, instance);
if (success)
{
result = (T)Enum.ToObject(enumType, instance);
}
else
{
result = default(T);
}
return success;
}
Antwoord 13
enigszins wegkomen van de oorspronkelijke vraag, maar ik vond een antwoord op Stack & Nbsp; Overloop Vraag Get int waarde van ENUM nuttig. Maak een statische klasse met public const int
Eigenschappen, zodat u eenvoudig een aantal gerelateerde int
Constanten kunt verzamelen en dan niet hoeft ze naar int
wanneer u ze gebruikt.
public static class Question
{
public static readonly int Role = 2;
public static readonly int ProjectFunding = 3;
public static readonly int TotalEmployee = 4;
public static readonly int NumberOfServers = 5;
public static readonly int TopBusinessConcern = 6;
}
Uiteraard zullen sommige van de functionaliteit van de ENUM-type verloren gaan, maar voor het opslaan van een stel database-ID-constanten, lijkt het een behoorlijk opgeruimde oplossing.
Antwoord 14
Om een tekenreeks te converteren naar ENUM of INT om Constant Constant te gebruiken, moeten we de functie van Enum.parse gebruiken. Hier is een YouTube-video https://www.youtube.com/watch?v=4nhx4vwdrdkdie daadwerkelijk demonstreert met string en hetzelfde geldt voor INT.
De code gaat zoals hieronder getoond waar “rood” de tekenreeks is en “mycolors” is de kleur enum die de kleurconstanten heeft.
MyColors EnumColors = (MyColors)Enum.Parse(typeof(MyColors), "Red");
Antwoord 15
Het volgende is een iets betere uitbreidingsmethode:
public static string ToEnumString<TEnum>(this int enumValue)
{
var enumString = enumValue.ToString();
if (Enum.IsDefined(typeof(TEnum), enumValue))
{
enumString = ((TEnum) Enum.ToObject(typeof (TEnum), enumValue)).ToString();
}
return enumString;
}
Antwoord 16
Deze parseert gehele getallen of snaren naar een doelwit-enum met gedeeltelijke matching in .NET 4.0 met behulp van generiek zoals in Tawani’s hulpprogramma’s . Ik gebruik het om opdrachtregelschakelaarvariabelen te converteren die onvolledig zijn. Omdat een ENUM niet null kan zijn, moet u logischerwijs een standaardwaarde bieden. Het kan zo worden genoemd:
var result = EnumParser<MyEnum>.Parse(valueToParse, MyEnum.FirstValue);
Hier is de code:
using System;
public class EnumParser<T> where T : struct
{
public static T Parse(int toParse, T defaultVal)
{
return Parse(toParse + "", defaultVal);
}
public static T Parse(string toParse, T defaultVal)
{
T enumVal = defaultVal;
if (defaultVal is Enum && !String.IsNullOrEmpty(toParse))
{
int index;
if (int.TryParse(toParse, out index))
{
Enum.TryParse(index + "", out enumVal);
}
else
{
if (!Enum.TryParse<T>(toParse + "", true, out enumVal))
{
MatchPartialName(toParse, ref enumVal);
}
}
}
return enumVal;
}
public static void MatchPartialName(string toParse, ref T enumVal)
{
foreach (string member in enumVal.GetType().GetEnumNames())
{
if (member.ToLower().Contains(toParse.ToLower()))
{
if (Enum.TryParse<T>(member + "", out enumVal))
{
break;
}
}
}
}
}
Ter info:de vraag ging over gehele getallen, die niemand vermeldde, ook expliciet zal converteren in Enum.TryParse()
Antwoord 17
Van een string: (Enum.Parse is verouderd, gebruik Enum.TryParse)
enum Importance
{}
Importance importance;
if (Enum.TryParse(value, out importance))
{
}
Antwoord 18
Je zou een soort ontspanningsoefening moeten inbouwen om robuuster te zijn.
public static T ToEnum<T>(dynamic value)
{
if (value == null)
{
// default value of an enum is the object that corresponds to
// the default value of its underlying type
// https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/default-values-table
value = Activator.CreateInstance(Enum.GetUnderlyingType(typeof(T)));
}
else if (value is string name)
{
return (T)Enum.Parse(typeof(T), name);
}
return (T)Enum.ToObject(typeof(T),
Convert.ChangeType(value, Enum.GetUnderlyingType(typeof(T))));
}
Testcase
[Flags]
public enum A : uint
{
None = 0,
X = 1 < 0,
Y = 1 < 1
}
static void Main(string[] args)
{
var value = EnumHelper.ToEnum<A>(7m);
var x = value.HasFlag(A.X); // true
var y = value.HasFlag(A.Y); // true
var value2 = EnumHelper.ToEnum<A>("X");
var value3 = EnumHelper.ToEnum<A>(null);
Console.ReadKey();
}
Antwoord 19
Hier is een uitbreidingsmethode die Int32
cast naar Enum
.
Het respecteert bitsgewijze vlaggen, zelfs als de waarde hoger is dan het maximaal mogelijke. Als je bijvoorbeeld een enum hebt met mogelijkheden 1, 2en 4, maar de int is 9, het begrijpt dat als 1bij afwezigheid van een 8. Hiermee kunt u gegevensupdates uitvoeren vóór code-updates.
public static TEnum ToEnum<TEnum>(this int val) where TEnum : struct, IComparable, IFormattable, IConvertible
{
if (!typeof(TEnum).IsEnum)
{
return default(TEnum);
}
if (Enum.IsDefined(typeof(TEnum), val))
{//if a straightforward single value, return that
return (TEnum)Enum.ToObject(typeof(TEnum), val);
}
var candidates = Enum
.GetValues(typeof(TEnum))
.Cast<int>()
.ToList();
var isBitwise = candidates
.Select((n, i) => {
if (i < 2) return n == 0 || n == 1;
return n / 2 == candidates[i - 1];
})
.All(y => y);
var maxPossible = candidates.Sum();
if (
Enum.TryParse(val.ToString(), out TEnum asEnum)
&& (val <= maxPossible || !isBitwise)
){//if it can be parsed as a bitwise enum with multiple flags,
//or is not bitwise, return the result of TryParse
return asEnum;
}
//If the value is higher than all possible combinations,
//remove the high imaginary values not accounted for in the enum
var excess = Enumerable
.Range(0, 32)
.Select(n => (int)Math.Pow(2, n))
.Where(n => n <= val && n > 0 && !candidates.Contains(n))
.Sum();
return Enum.TryParse((val - excess).ToString(), out asEnum) ? asEnum : default(TEnum);
}
Antwoord 20
In mijn geval moest ik het enum teruggeven van een WCF-service. Ik had ook een vriendelijke naam nodig, niet alleen de ENUM.TOSTRING ().
Hier is mijn WCF-klasse.
[DataContract]
public class EnumMember
{
[DataMember]
public string Description { get; set; }
[DataMember]
public int Value { get; set; }
public static List<EnumMember> ConvertToList<T>()
{
Type type = typeof(T);
if (!type.IsEnum)
{
throw new ArgumentException("T must be of type enumeration.");
}
var members = new List<EnumMember>();
foreach (string item in System.Enum.GetNames(type))
{
var enumType = System.Enum.Parse(type, item);
members.Add(
new EnumMember() { Description = enumType.GetDescriptionValue(), Value = ((IConvertible)enumType).ToInt32(null) });
}
return members;
}
}
Hier is de extensie-methode die de beschrijving van de ENUM krijgt.
public static string GetDescriptionValue<T>(this T source)
{
FieldInfo fileInfo = source.GetType().GetField(source.ToString());
DescriptionAttribute[] attributes = (DescriptionAttribute[])fileInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attributes != null && attributes.Length > 0)
{
return attributes[0].Description;
}
else
{
return source.ToString();
}
}
Implementatie:
return EnumMember.ConvertToList<YourType>();
Antwoord 21
Het kan u helpen om alle invoergegevens om te zetten in door de gebruiker gewenste enum. Stel dat je een opsomming hebt zoals hieronder die standaard intis. Voeg een Standaardwaarde toe aan het begin van je opsomming. Die wordt gebruikt bij helpersmethode wanneer er geen overeenkomst is gevonden met de invoerwaarde.
public enum FriendType
{
Default,
Audio,
Video,
Image
}
public static class EnumHelper<T>
{
public static T ConvertToEnum(dynamic value)
{
var result = default(T);
var tempType = 0;
//see Note below
if (value != null &&
int.TryParse(value.ToString(), out tempType) &&
Enum.IsDefined(typeof(T), tempType))
{
result = (T)Enum.ToObject(typeof(T), tempType);
}
return result;
}
}
NB:hier probeer ik de waarde in int te ontleden, omdat enum standaard intis
Als u enum als volgt definieert, is dat van het type byte.
public enum MediaType : byte
{
Default,
Audio,
Video,
Image
}
U moet het parseren op helpermethode van
wijzigen
int.TryParse(value.ToString(), out tempType)
Naar
byte.TryParse(value.ToString(), out tempType)
Ik controleer mijn methode voor de volgende ingangen
EnumHelper<FriendType>.ConvertToEnum(null);
EnumHelper<FriendType>.ConvertToEnum("");
EnumHelper<FriendType>.ConvertToEnum("-1");
EnumHelper<FriendType>.ConvertToEnum("6");
EnumHelper<FriendType>.ConvertToEnum("");
EnumHelper<FriendType>.ConvertToEnum("2");
EnumHelper<FriendType>.ConvertToEnum(-1);
EnumHelper<FriendType>.ConvertToEnum(0);
EnumHelper<FriendType>.ConvertToEnum(1);
EnumHelper<FriendType>.ConvertToEnum(9);
Sorry voor mijn Engels
Antwoord 22
De eenvoudige en duidelijke manier voor het gieten van een int te enum in C #:
public class Program
{
public enum Color : int
{
Blue = 0,
Black = 1,
Green = 2,
Gray = 3,
Yellow = 4
}
public static void Main(string[] args)
{
// From string
Console.WriteLine((Color) Enum.Parse(typeof(Color), "Green"));
// From int
Console.WriteLine((Color)2);
// From number you can also
Console.WriteLine((Color)Enum.ToObject(typeof(Color), 2));
}
}
Antwoord 23
Verschillende manieren om van en naar Enum
te werpen
enum orientation : byte
{
north = 1,
south = 2,
east = 3,
west = 4
}
class Program
{
static void Main(string[] args)
{
orientation myDirection = orientation.north;
Console.WriteLine(“myDirection = {0}”, myDirection); //output myDirection =north
Console.WriteLine((byte)myDirection); //output 1
string strDir = Convert.ToString(myDirection);
Console.WriteLine(strDir); //output north
string myString = “north”; //to convert string to Enum
myDirection = (orientation)Enum.Parse(typeof(orientation),myString);
}
}
Antwoord 24
Ik weet niet meer waar ik het deel van deze enum-extensie vandaan haal, maar het is van stackoverflow. Het spijt me hiervoor! Maar ik nam deze en wijzigde hem voor opsommingen met vlaggen.
Voor opsommingen met vlaggen deed ik dit:
public static class Enum<T> where T : struct
{
private static readonly IEnumerable<T> All = Enum.GetValues(typeof (T)).Cast<T>();
private static readonly Dictionary<int, T> Values = All.ToDictionary(k => Convert.ToInt32(k));
public static T? CastOrNull(int value)
{
T foundValue;
if (Values.TryGetValue(value, out foundValue))
{
return foundValue;
}
// For enums with Flags-Attribut.
try
{
bool isFlag = typeof(T).GetCustomAttributes(typeof(FlagsAttribute), false).Length > 0;
if (isFlag)
{
int existingIntValue = 0;
foreach (T t in Enum.GetValues(typeof(T)))
{
if ((value & Convert.ToInt32(t)) > 0)
{
existingIntValue |= Convert.ToInt32(t);
}
}
if (existingIntValue == 0)
{
return null;
}
return (T)(Enum.Parse(typeof(T), existingIntValue.ToString(), true));
}
}
catch (Exception)
{
return null;
}
return null;
}
}
Voorbeeld:
[Flags]
public enum PetType
{
None = 0, Dog = 1, Cat = 2, Fish = 4, Bird = 8, Reptile = 16, Other = 32
};
integer values
1=Dog;
13= Dog | Fish | Bird;
96= Other;
128= Null;
Antwoord 25
U gebruikt gewoon Expliciete conversieCast int naar enum of enum naar int
class Program
{
static void Main(string[] args)
{
Console.WriteLine((int)Number.three); //Output=3
Console.WriteLine((Number)3);// Outout three
Console.Read();
}
public enum Number
{
Zero = 0,
One = 1,
Two = 2,
three = 3
}
}
Antwoord 26
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace SamplePrograme
{
public class Program
{
public enum Suit : int
{
Spades = 0,
Hearts = 1,
Clubs = 2,
Diamonds = 3
}
public static void Main(string[] args)
{
//from string
Console.WriteLine((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));
}
}
}
Antwoord 27
Je doet gewoon zoals hieronder:
int intToCast = 1;
TargetEnum f = (TargetEnum) intToCast ;
Om ervoor te zorgen dat je alleen de juiste waarden cast en dat je anders een exception kunt gooien:
int intToCast = 1;
if (Enum.IsDefined(typeof(TargetEnum), intToCast ))
{
TargetEnum target = (TargetEnum)intToCast ;
}
else
{
// Throw your exception.
}
Houd er rekening mee dat het gebruik van IsDefined kostbaar is en zelfs meer dan alleen casten, dus het hangt af van uw implementatie om te beslissen of u het wilt gebruiken of niet.
Antwoord 28
Je kunt eenvoudig int casten naar enum
public enum DaysOfWeeks
{
Monday = 1,
Tuesday = 2,
Wednesday = 3,
Thursday = 4,
Friday = 5,
Saturday = 6,
Sunday = 7,
}
var day= (DaysOfWeeks)5;
Console.WriteLine("Day is : {0}", day);
Console.ReadLine();
Antwoord 29
U kunt een extensiemethode gebruiken.
public static class Extensions
{
public static T ToEnum<T>(this string data) where T : struct
{
if (!Enum.TryParse(data, true, out T enumVariable))
{
if (Enum.IsDefined(typeof(T), enumVariable))
{
return enumVariable;
}
}
return default;
}
public static T ToEnum<T>(this int data) where T : struct
{
return (T)Enum.ToObject(typeof(T), data);
}
}
Gebruik het zoals de onderstaande code:
Enum:
public enum DaysOfWeeks
{
Monday = 1,
Tuesday = 2,
Wednesday = 3,
Thursday = 4,
Friday = 5,
Saturday = 6,
Sunday = 7,
}
Gebruik:
string Monday = "Mon";
int Wednesday = 3;
var Mon = Monday.ToEnum<DaysOfWeeks>();
var Wed = Wednesday.ToEnum<DaysOfWeeks>();
Antwoord 30
Ik heb twee instructies nodig:
YourEnum possibleEnum = (YourEnum)value; // There isn't any guarantee that it is part of the enum
if (Enum.IsDefined(typeof(YourEnum), possibleEnum))
{
// Value exists in YourEnum
}