首页 / C# / C#Emit,如何编写if语句
C#Emit,如何编写if语句
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了C#Emit,如何编写if语句,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含5473字,纯文字阅读大概需要8分钟。
内容图文
![C#Emit,如何编写if语句](/upload/InfoBanner/zyjiaocheng/687/622b3f9a0ac34fe09ec4bfe5f0d6335b.jpg)
首先,我有一堂课
internal class Parent
{
protected void Write(string message, [CallerMemberName] string caller = null)
{
Console.WriteLine($"{caller} :: {message}");
}
}
我想动态创建一个类,该类具有属性“名称”,如果属性值更改,则调用write方法,如下所示
class Child : Parent
{
private string _name;
public string Name
{
get { return _name; }
set
{
06002
}
}
}
我想知道的是Highlight子句.
如何将其写入.
请帮忙.
我想要下面的一些代码
private static MethodBuilder BuildSetter(TypeBuilder typeBuilder, PropertyInfo property, FieldBuilder fieldBuilder, MethodAttributes attributes)
{
var setterBuilder = typeBuilder.DefineMethod($"set_{property.Name}", attributes, null, new Type[] { property.PropertyType });
var ilGenerator = setterBuilder.GetILGenerator();
ilGenerator.Emit(OpCodes.Ldarg_0); //this
ilGenerator.Emit(OpCodes.Ldarg_1); // the first one in arguments list
//code should be here
ilGenerator.Emit(OpCodes.Stfld, fieldBuilder);
ilGenerator.Emit(OpCodes.Ret);
return setterBuilder;
}
更新
var typeBuilder = moduleBuilder.DefineType(typeName, TypeAttributes.Public,typeof(PropertyChanged));
var t = typeof(PropertyChanged);
var m2 = t.GetMethod("ValueChanged");
您会看到,当我创建类型时,我使用了父类型,并且在父类型中有一个称为“ ValueChanged”的方法
protected void ValueChanged(object value,[CallerMemberName] string property = null)
我想在set方法中调用它.
更新2
private static MethodBuilder BuildSetter(TypeBuilder typeBuilder, PropertyInfo property, FieldBuilder fieldBuilder, MethodAttributes attributes)
{
var propertyType = property.PropertyType;
var setterBuilder = typeBuilder.DefineMethod($"set_{property.Name}", attributes, null, new Type[] { propertyType });
var setIl = setterBuilder.GetILGenerator();
Label exitSet = setIl.DefineLabel(); // define label to jump in case condition is false
setIl.Emit(OpCodes.Ldarg_0); // this
setIl.Emit(OpCodes.Ldfld, fieldBuilder); // _name field
setIl.Emit(OpCodes.Ldarg_1); // value
var inequality = propertyType.GetMethod("Equals", new[] { propertyType});
setIl.Emit(OpCodes.Callvirt, inequality); // '!=' method
setIl.Emit(OpCodes.Brtrue_S, exitSet); // check for inequality
setIl.Emit(OpCodes.Ldarg_0); // load string literal
setIl.Emit(OpCodes.Ldarg_1); // value
setIl.Emit(OpCodes.Ldstr, property.Name);
var m = typeBuilder.BaseType.GetMethod("ValueChanged", new Type[] {typeof(object),typeof(string) });
setIl.Emit(OpCodes.Call, m);
setIl.Emit(OpCodes.Ldarg_0); // this
setIl.Emit(OpCodes.Ldarg_1); // value
setIl.Emit(OpCodes.Stfld, fieldBuilder); // save the new value into _name
setIl.MarkLabel(exitSet); // mark the label
setIl.Emit(OpCodes.Ret); // return
return setterBuilder;
}
更新3
屏幕快照
更新4
也许,我已经找到错误原因,请参见Reflection Emit and Type Inheritance: Calling Base Type Constructors
更新5
最后,我得到了错误原因.这不是我在更新4上猜到的,它是由调用parent’t方法“ ValueChanged”引起的.在将参数传递给方法之前,如果原始数据类型为IsValueType,则应将其装箱为对象.请参阅下面的参考,
解决方法:
@AlbertK答案向您显示正确的方式,我将添加完整的代码.希望它会有所帮助.
我将所有内容都放在一种方法中.
// define assembly and module
var propertyName = "Name";
var propertyType = typeof(string);
var ab = AssemblyBuilder.DefineDynamicAssembly(
new AssemblyName("dynamicAssembly"),
AssemblyBuilderAccess.Save);
var mb = ab.DefineDynamicModule("dynamicModule", "dynamicModule.dll");
// define type, field and property
var tb = mb.DefineType("dynamicType");
var fb = tb.DefineField("_name", propertyType, FieldAttributes.Private);
var pb = tb.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, Type.EmptyTypes);
var get = tb.DefineMethod("get_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, propertyType, Type.EmptyTypes);
var set = tb.DefineMethod("set_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, null, new[] { propertyType });
// write the IL for the get method
var getIl = get.GetILGenerator();
getIl.Emit(OpCodes.Ldarg_0); // this
getIl.Emit(OpCodes.Ldfld, fb); // _name field
getIl.Emit(OpCodes.Ret);
// write the IL for the set method
var setIl = set.GetILGenerator();
Label exitSet = setIl.DefineLabel(); // define label to jump in case condition is false
setIl.Emit(OpCodes.Ldarg_0); // this
setIl.Emit(OpCodes.Ldfld, fb); // _name field
setIl.Emit(OpCodes.Ldarg_1); // value
var inequality = propertyType.GetMethod("op_Inequality", new[] { propertyType, propertyType });
setIl.Emit(OpCodes.Call, inequality); // '!=' method
setIl.Emit(OpCodes.Brfalse_S, exitSet); // check for inequality
setIl.Emit(OpCodes.Ldstr, "changedto:"); // load string literal
setIl.Emit(OpCodes.Ldarg_1); // value
var concat = propertyType.GetMethod("Concat", new[] { propertyType, propertyType });
setIl.Emit(OpCodes.Call, concat); // concat two strings (literal + value)
var writeline = typeof(Console).GetMethod("WriteLine", new[] { propertyType });
setIl.Emit(OpCodes.Call, writeline); // write
setIl.Emit(OpCodes.Ldarg_0); // this
setIl.Emit(OpCodes.Ldarg_1); // value
setIl.Emit(OpCodes.Stfld, fb); // save the new value into _name
setIl.MarkLabel(exitSet); // mark the label
setIl.Emit(OpCodes.Ret); // return
pb.SetGetMethod(get);
pb.SetSetMethod(set);
tb.CreateType(); // complete the type
ab.Save("dynamicModule.dll"); // save the assembly to disk
结果
internal class dynamicType
{
private string _name;
public string Name
{
get
{
return this._name;
}
set
{
if (this._name != value)
{
Console.WriteLine("changedto:" + value);
this._name = value;
}
}
}
}
内容总结
以上是互联网集市为您收集整理的C#Emit,如何编写if语句全部内容,希望文章能够帮你解决C#Emit,如何编写if语句所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。