Đây là bài tập học tập. Tôi đã tạo ra một phương thức lấy một Foo và một chuỗi và đặt thuộc tính A. Tôi đã sử dụng trình gỡ bỏ Reflector để tạo mã phát ra sau. Tháo gỡ trông như thế này:Tạo DynamicMethod để gán giá trị cho một thuộc tính?
.method private hidebysig static void Spork(class ConsoleTesting.Foo f, string 'value') cil managed
{
.maxstack 8
L_0000: ldarg.0
L_0001: ldarg.1
L_0002: callvirt instance void ConsoleTesting.Foo::set_A(string)
L_0007: ret
}
Ok, vì vậy tôi theo mô hình đang Emit của tôi sau đó:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Reflection.Emit;
namespace ConsoleTesting
{
class Foo
{
public string A { get; set; }
}
class Program
{
static Action<Foo, string> GenMethodAssignment(string propName)
{
MethodInfo setMethod = typeof(Foo).GetMethod("get_" + propName);
if (setMethod == null)
throw new InvalidOperationException("no property setter available");
Type[] argTypes = new Type[] { typeof(Foo), typeof(String) };
DynamicMethod method = new DynamicMethod("__dynamicMethod_Set_" + propName, null, argTypes, typeof(Program));
ILGenerator IL = method.GetILGenerator();
IL.Emit(OpCodes.Ldarg_0);
IL.Emit(OpCodes.Ldarg_1);
IL.Emit(OpCodes.Callvirt, setMethod);
IL.Emit(OpCodes.Ret);
method.DefineParameter(1, ParameterAttributes.In, "instance");
method.DefineParameter(2, ParameterAttributes.In, "value");
Action<Foo, string> retval = (Action<Foo, string>)method.CreateDelegate(typeof(Action<Foo, string>));
return retval;
}
static void Main(string[] args)
{
Foo f = new Foo();
var meth = GenMethodAssignment("A");
meth(f, "jason");
Console.ReadLine();
}
}
tôi nhận được ngoại lệ này:
JIT Compiler encountered an internal limitation.
gì cho Miễn phí nào đó có nghĩa là gì và làm thế nào để sửa nó?
EDIT:
Tôi nghĩ có lẽ đó là bởi vì phương pháp mục tiêu là cá nhân, nhưng tôi không như vậy chắc chắn. Từ số DynamicMethod MSDN page:
Ví dụ mã sau tạo ra DynamicMethod được liên kết hợp lý với loại. Hiệp hội này cung cấp cho nó quyền truy cập vào các thành viên riêng tư thuộc loại đó.
Bạn đang truy cập phương thức "get_"; đây có phải là lỗi đánh máy trong bài viết của bạn không? Lưu ý rằng bạn có thể truy cập thuộc tính theo tên và sử dụng phương thức GetSetMethod() trên đối tượng PropertyInfo; theo cách này, bạn không dựa vào quy ước C# của "get_" và "set_". –
Tôi đã làm, tuy nhiên, sửa lỗi chính tả ngay bây giờ. IL chứa AStr, thay vì A, vì tôi đã đổi tên thuộc tính cho mục đích của bài đăng này. – Amy
Ah, tôi đã giải thích sai câu đầu tiên của nhận xét của bạn. Bạn hoàn toàn đúng. – Amy