2011-11-03 16 views
3

今日、FieldInfo.SetValue()を使用してフィールドを設定しようとすると、DynamicObjectを2番目の引数として使用して問題が発生しました。私の場合、フィールドはGuidで、DynamicObjectになります(TryConvertを使用)。ArgumentExceptionで失敗します。DynamicObjectを引数として使用してFieldInfo.SetValueを使用する

問題を示していくつかのコード:

​​3210

私はC#4の全体dynamicnessに非常に慣れていないんだけど、これは動作するはず何かのように私には感じた..私は間違って何をやっているの?これを行う別の方法がありますか?

答えて

4

いいえ、これは機能しません。動的部分はコードが終了するところで終了するためです。コンパイラは、メソッドの呼び出しが動的であること

void SetValue(Object obj, Object value) 

のシグネチャを持つメソッドを呼び出しているが、それはただ MyDynamicObjのインスタンスへの参照を渡して終了する予定です。呼び出しは実行時に解決されますが、SetValueの中には、参照を渡しているオブジェクトの動的な性質について何もわかっていません。

基本的には、 code - C#4コンパイラがすべてのトリックを行うことに関係するビット。その変換を実行しなければなりません。、次にSetFieldと呼ぶことができます。

別の言い方をすれば、フィールドXNameSetFieldを呼び出すのと同じですが、文字列を渡します。はい、stringからXNameに変換されていますが、これを行うにはSetFieldの仕事ではありません。これがコンパイラの仕事です。あなたは、これはコンパイラを作ることによって仕事を得ることができます今すぐ

、作業の一部を行いますが、あなたはまだ反映して、いくつかの操作を行う必要があります。あなたはTryConvertを呼び出すために明示的なキャストが必要

static void Main(string[] args) 
{ 
    dynamic myObj = new MyDynamicObj(); 

    var test = new Test(); 
    var testField = typeof(Test).GetField("MyField"); 

    var method = typeof(Program) 
     .GetMethod("Convert", BindingFlags.Static | BindingFlags.NonPublic); 
    method = method.MakeGenericMethod(testField.FieldType); 

    object converted = method.Invoke(null, new object[] {myObj}); 
    testField.SetValue(test, converted); 
} 

static T Convert<T>(dynamic input) 
{ 
    return input; 
} 
+0

です。もちろん。 *額を叩く* – CodingInsomnia

+0

だから、その周りには何か?実行時にタイプのみがわかっているので、何とか変換をトリガーできますか? – CodingInsomnia

+0

@コーディングインソムニア:私の編集を参照してください:) –

0

testField.SetValue(test, (Guid)myObj); 

これが必要なのかどうかはわかりません。おそらく、反射的に言えるような方法があります((DynamicObject)myObj).TryConvert(/*reflected destination type here*/, result)

その他の試みは失敗しましたが、一部のインターフェースは実装する必要があるため、基本的にはTryConvertを使用していませんが、

Type secondType = testField.FieldType; 

    TypeConverter tc = TypeDescriptor.GetConverter(typeof(MyDynamicObj)); 
    object secondObject = tc.ConvertTo(myObj,typeof(Guid)); 
    //var secondObject = Convert.ChangeType(myObj, secondType);//Activator.CreateInstance(secondType); 
    //secondObject = myObj; 
    testField.SetValue(test, secondObject); 
+0

"実際の"シナリオでは、実行時に型だけが分かっているので、あなたが言及したTryConvert呼び出しのようなものが必要です。そのようなものを試してみましたが、実行することができませんでした.. – CodingInsomnia

関連する問題