2014-03-06 34 views
1

目前,我有以下的IL代碼:ExpandoObject C#IL

var method = new DynamicMethod("", typeof(object), new Type[ 0 ]); 
var emiter = method.GetILGenerator(); 
var expando = emiter.DeclareLocal(typeof(ExpandoObject)); 
emiter.Emit(OpCodes.Newobj, typeof(ExpandoObject).GetConstructors()[ 0 ]); 
emiter.Emit(OpCodes.Stloc, expando); 

var value = emiter.DeclareLocal(typeof(int)); 
emiter.Emit(OpCodes.Ldc_I4_1); 
emiter.Emit(OpCodes.Stloc, value); 

emiter.Emit(OpCodes.Ldloc, expando); 
emiter.Emit(OpCodes.Ldnull); 
emiter.Emit(OpCodes.Ldc_I4, -1); 
emiter.Emit(OpCodes.Ldloc, value); 
if (value.LocalType.IsValueType) 
    emiter.Emit(OpCodes.Box, value.LocalType); 
else 
{ 
    emiter.Emit(OpCodes.Castclass, typeof(object)); 
} 
emiter.Emit(OpCodes.Ldstr, "Test"); 
emiter.Emit(OpCodes.Ldc_I4_0); 
emiter.Emit(OpCodes.Ldc_I4_1); 
emiter.Emit(OpCodes.Call, typeof(ExpandoObject).GetMethod("TrySetValue", BindingFlags.Instance | BindingFlags.NonPublic)); 

emiter.Emit(OpCodes.Ldloc, expando); 
emiter.Emit(OpCodes.Ret); 
var @delegate = (Func<dynamic>)method.CreateDelegate(typeof(Func<dynamic>)); 

var result = @delegate().Test; 

它工作正常,當我最初寫的印記,但現在我把它轉化爲DynamicMethod的我得到這個錯誤。我完全複製了Sigil代碼,並且三重檢查了它。有沒有人有一個想法在此先感謝。

嘗試通過方法 'DynamicClass。()' 來訪問方法 'System.Dynamic.ExpandoObject.TrySetValue(System.Object的,的Int32,System.Object的,System.String,布爾值布爾值)' 失敗。

回答

3

我通過向DynamicMethod構造函數添加restrictedSkipVisibility來解決此問題。

var method = new DynamicMethod("", typeof(object), new Type[ 0 ], true ); 
var emiter = method.GetILGenerator(); 
var expando = emiter.DeclareLocal(typeof(ExpandoObject)); 
emiter.Emit(OpCodes.Newobj, typeof(ExpandoObject).GetConstructors()[ 0 ]); 
emiter.Emit(OpCodes.Stloc, expando); 

var value = emiter.DeclareLocal(typeof(int)); 
emiter.Emit(OpCodes.Ldc_I4_1); 
emiter.Emit(OpCodes.Stloc, value); 

emiter.Emit(OpCodes.Ldloc, expando); 
emiter.Emit(OpCodes.Ldnull); 
emiter.Emit(OpCodes.Ldc_I4, -1); 
emiter.Emit(OpCodes.Ldloc, value); 
if (value.LocalType.IsValueType) 
    emiter.Emit(OpCodes.Box, value.LocalType); 
else 
{ 
    emiter.Emit(OpCodes.Castclass, typeof(object)); 
} 
emiter.Emit(OpCodes.Ldstr, "Test"); 
emiter.Emit(OpCodes.Ldc_I4_0); 
emiter.Emit(OpCodes.Ldc_I4_1); 
emiter.Emit(OpCodes.Call, typeof(ExpandoObject).GetMethod("TrySetValue", BindingFlags.Instance | BindingFlags.NonPublic)); 

emiter.Emit(OpCodes.Ldloc, expando); 
emiter.Emit(OpCodes.Ret); 
var @delegate = (Func<dynamic>)method.CreateDelegate(typeof(Func<dynamic>)); 

var result = @delegate().Test;