2011-08-15 8 views
4

以下は、enumを素早くニップするために使用できるという点で便利なコードです。 CurrentEnumは、文字列を提供するために使用されたenumへの参照を格納します。この場合、 "Bald"は変更できます。.NETと同じように動作するSilverlightでGetEnumValues拡張メソッドを作成するにはどうすればよいですか?

私がしようとしているのは、SilverlightでGetEnumValues関数を持たない同じ機能を複製することです。好ましいソリューションは、以下の私の例と同じように使用できる拡張メソッドです。

class Program 
{ 
    enum Cats { Fluffy, Furry, Bald }; 
    enum Dogs { Big, Fat, Ugly }; 

    static Type CurrentEnum = typeof(Cats); 

    static void Main(string[] args) 
    { 
     Int32 i = (Int32)Enum.Parse(CurrentEnum, "Bald", true); 
     i = i == CurrentEnum.GetEnumValues().Length - 1 ? 0 : i + 1; 
     String nextValue = CurrentEnum.GetEnumValues().GetValue(i).ToString(); 

     Console.WriteLine(nextValue); 
     Console.ReadKey(); 
    } 
} 

UPDATE:

public static class Extensions 
{ 
    public static Array GetEnumValues(this Type enumType) 
    { 
     if (enumType == null) throw new ArgumentException("Type 'enumType' cannot be null"); 
     if (!enumType.IsEnum) throw new ArgumentException("Type '" + enumType.Name + "' is not an enum"); 

     Int32 i = 0; 
     Boolean bDefined = true; 
     List<String> list = new List<String>(); 

     do 
     { 
      if (Enum.IsDefined(enumType, i)) 
      {      
       list.Add(Enum.GetName(enumType, i)); 
       ++i; 
      } 
      else 
      { 
       bDefined = false; 
      } 
     } 
     while (bDefined); 

     return list.ToArray(); 
    } 
} 
+3

[この質問](http://stackoverflow.com/questions/1038234)で動作しなかったことを教えていただければ、本当に助かります。重複している可能性について疑問を呈するのではなく、私たちはあなたを助けてくれるでしょう。 –

+0

私はすでに消滅したコメントに応じてこれを行っていました。その質問のコメントに記載されているように、ソリューションは.NETと同じように動作しないため、私の例ではCurrentEnum変数では動作しません。私の質問は非常に具体的で、私の例はテストです。 – descf

+0

私はそれを無視したことは認めますが、回答の形式が私には見えず、投票が1つしかないためです。おそらく私はそれをもっとよく見てみるべきです。 – descf

答えて

4

私が(未テスト)を推測しなければならなかった場合::

ここ

が、私は今の上決定しているものです

public static Array GetValues(Type type) 
    { 
     var fields = type.GetFields(BindingFlags.Static | BindingFlags.Public); 
     Array result = Array.CreateInstance(type, fields.Length); 
     for(int i = 0 ; i < fields.Length ; i++) 
     { 
      result.SetValue(Enum.ToObject(type, fields[i].GetValue(null)), i); 
     } 
     return result; 
    } 

なお、Iドンのご注文はになります。フィールドの順序は明示的に定義されていません。したがって、特定の順序で値を取得するためにこれを使用してください

+0

テストされていない場合でも悪くない。エクステンションにも簡単に変換できます。 – descf

3

Iterating through an enumeration in Silverlight?にはもう1つの質問がありますが、答えは全くありません。GetEnumValues()(とGetEnumNames())の仕組みを正確に反映した実装はありません。私はその質問からの答えの1つを使用して、必要なものを提供するソリューションを作成しました。私はこれがSilverlightでのこれらの関数の.NET機能を正確に複製していると信じており、関数を作成して使用法をテストするために使用したSilverlight用のテストプロジェクト全体をアップロードしました:GetEnumValuesSilverlightImpl-StackOverflow-7062208.zip

アプリケーション自体は、ボタンとテキストエリアが1つの単一フォームです。ボタンをクリックすると、4つの異なる列挙体の3つの値のそれぞれを反復し、その値をフォームに記録します。テキストエリアは単語の折り返しを行わないので、テキストエリアよりも値を大きくしたい場合には、これを考慮する必要がありますので、余分なテストケースを追加するのは簡単です。私はオリジナルのポスターのテストケースをテストし、2つの元の列挙型の3つの値をすべて書き出し、3つの連続しない値を持つ列挙型の3つの値をすべて書き出し、[Flag]列挙型3つの異なるフラグ値。

関連コード:

EnumValuesExtensions.csに:関数を含む拡張クラスは

using System; 
using System.Linq; 
using System.Reflection; 

namespace SilverlightApplication1 
{ 
    public static class EnumValuesExtensions 
    { 
     public static Array GetEnumValues(this Type EnumType) 
     { 
      if (!EnumType.IsEnum) 
       throw new ArgumentException("GetEnumValues: Type '" + EnumType.Name + "' is not an enum"); 

      return 
       (
        from field in EnumType.GetFields(BindingFlags.Public | BindingFlags.Static) 
        where field.IsLiteral 
        select (object)field.GetValue(null) 
       ) 
       .ToArray(); 
     } 

     public static string[] GetEnumNames(this Type EnumType) 
     { 
      if (!EnumType.IsEnum) 
       throw new ArgumentException("GetEnumNames: Type '" + EnumType.Name + "' is not an enum"); 

      return 
       (
        from field in EnumType.GetFields(BindingFlags.Public | BindingFlags.Static) 
        where field.IsLiteral 
        select field.Name 
       ) 
       .ToArray(); 
     } 
    } 
} 

MainPage.xaml.csを呼び出し:テストフォーム

ためXAML:テストコード

​​

MainPage.xamlを含むフォーム源

<UserControl x:Class="SilverlightApplication1.MainPage" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d" 
    d:DesignHeight="430" d:DesignWidth="400"> 

    <Grid x:Name="LayoutRoot" Background="White"> 
     <TextBlock Height="377" HorizontalAlignment="Left" Margin="12,41,0,0" Name="textBlock1" Text="" VerticalAlignment="Top" Width="376" /> 
     <Button Content="Run Tests" Height="23" HorizontalAlignment="Left" Margin="12,12,0,0" Name="btnRunTests" VerticalAlignment="Top" Width="75" Click="btnRunTests_Click" /> 
    </Grid> 
</UserControl> 

これらのテストはSilverlight 3で実行されており、GetEnumValues()拡張機能は.NETのGetEnumValues()関数と同じように機能します.ToTo()が呼び出されたときに列挙型名を返し、キャストされたとき(int)。

私はGetEnumNames()拡張機能をテストしていませんが、GetEnumValues()拡張機能の類推によってかなりはっきりと動作しますが、何か問題があれば喜んで見ていきます。機能の基礎を形成a similar questiontheir answerためptoinsonShimmy

おかげで、私はこの質問に答えるために書きました。

+0

「ふわふわ」を返す方法についてもう少し説明する必要があると思います。現時点では、intのリストをまとめているように見えますか? – descf

+0

これはSilverlightでテストしていますか?この関数はintのリストを返します。intのリストの中でどのようにふわふわしているのですか? – descf

+0

いいえ、私はそうではありませんでした。そして、上記のコードで2番目の必要な置換えが失われてしまったので、リストについてのことがわかりました。これはType.GetEnumValues()呼び出しと同じではありません。その呼び出しは列挙型の実際の配列を返します。そのため、コードでGetEnumNames()を呼び出す必要はありません.ToToString()を使用して列挙型にキャストしますname文字列ですが、intにキャストすると値が得られます。そして、与えられた関数内のコードは文字列部分を与えなかった、ちょうどあなたがそれを得ることができると言いました。私は今、同等のものを実装するバージョンを持っており、その答えを更新しています。 – shelleybutterfly

0

これには2つのスレッドがあり、何もできませんでした。

public static Array GetEnumValues(this Type enumType) 
    { 
     List<int> enumerations = new List<int>(); 
     FieldInfo[] fields = enumType.GetFields(BindingFlags.Static | BindingFlags.Public); 
     object enumObj = enumType.GetType(); 

     foreach (FieldInfo fieldInfo in fields) 
     { 
      enumerations.Add((int)fieldInfo.GetValue(enumObj)); 
     } 
     return enumerations.ToArray(); 
    } 
関連する問題