C#の列挙型を反復? (のSystem.Arrayインデックス作成)
-
20-08-2019 - |
質問
私は、次のコードを持っています:
// Obtain the string names of all the elements within myEnum
String[] names = Enum.GetNames( typeof( myEnum ) );
// Obtain the values of all the elements within myEnum
Array values = Enum.GetValues( typeof( myEnum ) );
// Print the names and values to file
for ( int i = 0; i < names.Length; i++ )
{
print( names[i], values[i] );
}
しかし、私はできないのインデックス値。これを行うための簡単な方法はありますか?
または私は完全に何かを見逃している!
解決
Array values = Enum.GetValues(typeof(myEnum));
foreach( MyEnum val in values )
{
Console.WriteLine (String.Format("{0}: {1}", Enum.GetName(typeof(MyEnum), val), val));
}
それとも、あなたが返されるのSystem.Arrayにキャストすることができます:
string[] names = Enum.GetNames(typeof(MyEnum));
MyEnum[] values = (MyEnum[])Enum.GetValues(typeof(MyEnum));
for( int i = 0; i < names.Length; i++ )
{
print(names[i], values[i]);
}
しかし、あなたはによりgetNames名前を返すようにgetValuesが同じ順序で値を返すことを確認することができますか?
他のヒント
あなたは、配列をキャストする必要があります - あなたが頼めば返される配列は、すなわちmyEnum[]
要求されたタイプで、実際にはtypeof(myEnum)
:
myEnum[] values = (myEnum[]) Enum.GetValues(typeof(myEnum));
次にvalues[0]
など
あなたは配列の異なる種類にその配列をキャストすることができます:
myEnum[] values = (myEnum[])Enum.GetValues(typeof(myEnum));
か、整数値を必要とします。
int[] values = (int[])Enum.GetValues(typeof(myEnum));
あなたは当然のものとキャストの配列を反復処理することができます。)
どのように辞書のリストについてはどうですか?
Dictionary<string, int> list = new Dictionary<string, int>();
foreach( var item in Enum.GetNames(typeof(MyEnum)) )
{
list.Add(item, (int)Enum.Parse(typeof(MyEnum), item));
}
そしてもちろん、あなたの列挙型の値があるものは何でも辞書値の型を変更することができます。
興味深い可能性を持つ別の解決策、:
enum Days { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday }
static class Helpers
{
public static IEnumerable<Days> AllDays(Days First)
{
if (First == Days.Monday)
{
yield return Days.Monday;
yield return Days.Tuesday;
yield return Days.Wednesday;
yield return Days.Thursday;
yield return Days.Friday;
yield return Days.Saturday;
yield return Days.Sunday;
}
if (First == Days.Saturday)
{
yield return Days.Saturday;
yield return Days.Sunday;
yield return Days.Monday;
yield return Days.Tuesday;
yield return Days.Wednesday;
yield return Days.Thursday;
yield return Days.Friday;
}
}
ここでもう一つあります。私たちは、EnumValuesのフレンドリ名を提供する必要がありました。私たちは、それぞれの列挙値のカスタム文字列値を表示するためにSystem.ComponentModel.DescriptionAttributeを使用しました。
public static class StaticClass
{
public static string GetEnumDescription(Enum currentEnum)
{
string description = String.Empty;
DescriptionAttribute da;
FieldInfo fi = currentEnum.GetType().
GetField(currentEnum.ToString());
da = (DescriptionAttribute)Attribute.GetCustomAttribute(fi,
typeof(DescriptionAttribute));
if (da != null)
description = da.Description;
else
description = currentEnum.ToString();
return description;
}
public static List<string> GetEnumFormattedNames<TEnum>()
{
var enumType = typeof(TEnum);
if (enumType == typeof(Enum))
throw new ArgumentException("typeof(TEnum) == System.Enum", "TEnum");
if (!(enumType.IsEnum))
throw new ArgumentException(String.Format("typeof({0}).IsEnum == false", enumType), "TEnum");
List<string> formattedNames = new List<string>();
var list = Enum.GetValues(enumType).OfType<TEnum>().ToList<TEnum>();
foreach (TEnum item in list)
{
formattedNames.Add(GetEnumDescription(item as Enum));
}
return formattedNames;
}
}
使用中の
public enum TestEnum
{
[Description("Something 1")]
Dr = 0,
[Description("Something 2")]
Mr = 1
}
static void Main(string[] args)
{
var vals = StaticClass.GetEnumFormattedNames<TestEnum>();
}
これは "何か2"、 "何か1" を返す終了します。
foreachループを使用することについて、多分あなたはそれと仕事ができるか?
int i = 0;
foreach (var o in values)
{
print(names[i], o);
i++;
}
おそらくそのような何か?
古い問題が、わずかクリーナーアプローチLINQの.Cast<>()
var values = Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>();
foreach(var val in values)
{
Console.WriteLine("Member: {0}",val.ToString());
}
アレイを使用すると、指定したインデックスの値を取得するために使用することができますGetValueメソッド(Int32)をメソッドを持っています。
あなたは、この使用してフォーマット文字列を簡素化することができます。
:私は、用法メッセージに次のコードを使用しますwriter.WriteLine("Exit codes are a combination of the following:");
foreach (ExitCodes value in Enum.GetValues(typeof(ExitCodes)))
{
writer.WriteLine(" {0,4:D}: {0:G}", value);
}
D形式指定子は、小数として列挙値をフォーマットします。進出力を与えるX指定子もあります。
G指定子は、文字列として列挙型をフォーマットします。フラグは列挙型に適用される属性の場合、結合値も同様にサポートされています。フラグが常に存在しているかのように動作するF指定子があります。
を参照してくださいEnum.Format()。
Enum.GetValues結果では、int型にキャストすると、数値を生成します。 toString()を使用すると、フレンドリ名を生成します。 Enum.GetNameへの他の呼び出しは必要ありません。
public enum MyEnum
{
FirstWord,
SecondWord,
Another = 5
};
// later in some method
StringBuilder sb = new StringBuilder();
foreach (var val in Enum.GetValues(typeof(MyEnum))) {
int numberValue = (int)val;
string friendyName = val.ToString();
sb.Append("Enum number " + numberValue + " has the name " + friendyName + "\n");
}
File.WriteAllText(@"C:\temp\myfile.txt", sb.ToString());
// Produces the output file contents:
/*
Enum number 0 has the name FirstWord
Enum number 1 has the name SecondWord
Enum number 5 has the name Another
*/
ここでは、カスタム列挙型のオブジェクトを反復処理するための簡単な方法です。
For Each enumValue As Integer In [Enum].GetValues(GetType(MyEnum))
Print([Enum].GetName(GetType(MyEnum), enumValue).ToString)
Next
古代の質問が、3Daveの答えは、最も簡単な方法を提供しました。私は、デバッグのために、データベース内の列挙型の値をデコードするためのSQLスクリプトを生成するために小さなヘルパーメソッドを必要としていました。それは素晴らしい仕事ます:
public static string EnumToCheater<T>() {
var sql = "";
foreach (var enumValue in Enum.GetValues(typeof(T)))
sql += $@"when {(int) enumValue} then '{enumValue}' ";
return $@"case ?? {sql}else '??' end,";
}
私は、静的メソッドでそれを持っているので、使い方は次のとおりです。
var cheater = MyStaticClass.EnumToCheater<MyEnum>()