Привет всем
У меня есть код, который создает новую среду выполнения TYPE, он устанавливает методы GET и SET с помощью MethodBuilder. (Это пример из Интернета, и благодаря парню, который его написал, я, к сожалению, потерял ссылку на него, но он в моих мыслях)
TypeBuilder typeBuilder = module.DefineType("MyClass", TypeAttributes.Public | TypeAttributes.Class);
Таким образом я добавляю метод к классу.
MethodAttributes GetSetAttr =
MethodAttributes.Public |
MethodAttributes.HideBySig;
// Define the "get" accessor method for current private field.
MethodBuilder currGetPropMthdBldr =
typeBuilder.DefineMethod("get_value",
GetSetAttr,
typeof(string),
Type.EmptyTypes);
// Intermediate Language stuff...
ILGenerator currGetIL = currGetPropMthdBldr.GetILGenerator();
currGetIL.Emit(OpCodes.Ldarg_0);
currGetIL.Emit(OpCodes.Ldfld, field);
currGetIL.Emit(OpCodes.Ret);
// Define the "set" accessor method for current private field.
MethodBuilder currSetPropMthdBldr =
typeBuilder.DefineMethod("set_value",
GetSetAttr,
null,
new Type[] { typeof(string) });
// Again some Intermediate Language stuff...
ILGenerator currSetIL = currSetPropMthdBldr.GetILGenerator();
currSetIL.Emit(OpCodes.Ldarg_0);
currSetIL.Emit(OpCodes.Ldarg_1);
currSetIL.Emit(OpCodes.Stfld, field);
currSetIL.Emit(OpCodes.Ret);
// Last, we must map the two methods created above to our PropertyBuilder to
// their corresponding behaviors, "get" and "set" respectively.
property.SetGetMethod(currGetPropMthdBldr);
property.SetSetMethod(currSetPropMthdBldr);
Он работает нормально, однако я хотел бы изменить метод установки на что-то более сложное, поэтому я пишу этот тестовый код.
открытый класс Клиент {частная строка _name; общедоступная строка name {get {return _name; } set {if (string.IsNullOrEmpty (value)) {throw new ValidationException ("Пожалуйста, установите значение"); } _name = значение; }} публичная строка lastname {get; установленный; }}
Скомпилируйте, а затем используйте Reflector, чтобы получить MSIL.
.method public hidebysig specialname instance void set_name(string 'value') cil managed
{
.maxstack 2
.locals init (
[0] bool CS$4$0000)
L_0000: nop
L_0001: ldarg.1
L_0002: call bool [mscorlib]System.String::IsNullOrEmpty(string)
L_0007: ldc.i4.0
L_0008: ceq
L_000a: stloc.0
L_000b: ldloc.0
L_000c: brtrue.s L_001a
L_000e: nop
L_000f: ldstr "Please set a value"
L_0014: newobj instance void [System.ComponentModel.DataAnnotations]System.ComponentModel.DataAnnotations.ValidationException::.ctor(string)
L_0019: throw
L_001a: ldarg.0
L_001b: ldarg.1
L_001c: stfld string AnnotationTest.MainPage/Customer::_name
L_0021: ret
}
Итак, задача состоит в том, чтобы реализовать это в коде SET EMIT.
// Again some Intermediate Language stuff...
ILGenerator currSetIL = currSetPropMthdBldr.GetILGenerator();
currSetIL.Emit(OpCodes.Ldarg_0); currSetIL.Emit(OpCodes.Ldarg_1); currSetIL.Emit(OpCodes.Stfld, field); currSetIL.Emit(OpCodes.Ret);
Вот где я ошибаюсь, я не могу заставить его работать. Похоже, что я могу «просто» скопировать код, а мои навыки работы с MSIL ограничены. вот моя ошибка.
currSetIL.Emit(OpCodes.Nop); // L_0000: nop
currSetIL.Emit(OpCodes.Ldarg_1); // L_0001: ldarg.1
currSetIL.Emit(OpCodes.Call bool [mscorlib]System.String::IsNullOrEmpty(string);// call bool [mscorlib]System.String::IsNullOrEmpty(string)
В строке 3 эти красные подчеркивания указывают на ошибки ...
- Bool = ") Expetced"
- [mscorlib] System = "; ожидается"
- :: = ". ожидается"
- и последний) дает "недопустимую строку термина выражения"
Интересно, почему я не могу использовать отражатель, код должен быть в порядке? или?
Решение - найти программу / метод, отображающий код MSIL, который можно использовать в операторе EMIT.
Это всего лишь пример, так что код будет изменен, поэтому это не решение для ответа на правильный код (все, что было бы неплохо, чтобы пример работал), а более постоянный «способ» получения правильного MSIL из C #.
Пью, длинный вопрос, надеюсь, у меня здесь все есть.
С уважением, ReLoad
Expression(особенно в случае новых объектов). У вас есть пример того, чего вы хотите достичь? то есть вы можете опубликовать эквивалент C # того, что вы хотите? - person Marc Gravell   schedule 15.01.2010