2011-12-27 10 views
0

私のプログラムでは、列挙体を使用してオブジェクトの現在の状態を表しています。私は、この列挙体の値を1つずつ順番に調べることができるようにしたいと考えています。列挙型の値が数値的に連続し、0で始まるという事実は、与えられたものです。複数のアセンブリでの動的型のキャスト動作

列挙をインクリメントする関数を記述しようとしている最中にループすると問題が発生しました。

public static TEnum IncrWrap<TEnum>(TEnum value) 
{ 
    int len = Enum.GetNames(typeof(TEnum)).Length; 
    dynamic wrapper = value; 
    dynamic newValue = ((int)wrapper + 1) % len; 
    return (TEnum)newValue; 
} 
IncrWrap

方法は、それを呼び出すオブジェクトと同じアセンブリ(プロジェクト)に存在する場合、それが完璧に動作。しかし、RuntimeBinderExceptionwrapperに変換してintにキャストしようとすると、別のプロジェクトに移動して(より多くのものがそれを利用できるように)、「タイプを変換できません」というメッセージが表示されます。 System.Enum 'を' int 'に変更します。

Whats up?異なるアセンブリから関数を呼び出すと、その関数が異なる動作をする理由がわかりません。 dynamic私は理解できませんか?これを行うにはリフレクションを使用する必要はありません。

答えて

1

残念ながら、ここではいくつかの問題が列挙されています。まず、列挙型は、char以外の整数型を持つことができます。第2に、列挙型に根本的な型の値が徐々に増加するという保証はありません。最後に、C#言語は幾分有用な汎用タイプ制約System.Enumをサポートしていません。言ったことすべてで、私はあなたが少し違っあなたの問題を解決できると信じている:

public static TEnum NextEnum<TEnum>(TEnum value) 
{ 
    if (!typeof(TEnum).IsEnum) 
     throw new ArgumentException("Expected type of System.Enum", "value"); 

    var values = Enum.GetValues(typeof (TEnum)); 
    var index = Array.IndexOf(values, value); 
    return (TEnum)Enum.ToObject(typeof (TEnum), values.GetValue((index + 1) % values.Length)); 
} 

私はあなたがそれはあなたのダイナミックなソリューションを使用して仕事を得ることができたことを実際に驚いています。

+0

別の問題があります:Array.IndexOfは、 'value'の値がenumの定義された値の1つでない場合、-1を返します。 – phoog

+0

素晴らしい!ありがとう。なぜ私のメソッドが2つの状況で異なった振る舞いをするのか不思議ですが、このソリューションは間違いなく優れています。 – Lucina

関連する問題