CIL 中的字符串生成器 (MSIL)
我正在尝试生成采用 StringBuilder 的代码,并将类中所有属性的值写入字符串。我有以下内容,但我目前在以下代码中收到“无效的方法令牌”:
public static DynamicAccessor<T> CreateWriter(T target) //Target class to *serialize*
{
DynamicAccessor<T> dynAccessor = new DynamicAccessor<T>();
MethodInfo AppendMethod = typeof(StringBuilder).GetMethod("Append", new[] { typeof(Object) }); //Append method of Stringbuilder
var method = new DynamicMethod("ClassWriter", typeof(StringBuilder), new[] { typeof(T) }, typeof(T), true);
var generator = method.GetILGenerator();
LocalBuilder sb = generator.DeclareLocal(typeof(StringBuilder)); //sb pointer
generator.Emit(OpCodes.Newobj, typeof(StringBuilder)); //make our string builder
generator.Emit(OpCodes.Stloc, sb); //make a pointer to our new sb
//iterate through all the instance of T's props and sb.Append their values.
PropertyInfo[] props = typeof(T).GetProperties();
foreach (var info in props)
{
generator.Emit(OpCodes.Callvirt, info.GetGetMethod()); //call the Getter
generator.Emit(OpCodes.Ldloc, sb); //load the sb pointer
generator.Emit(OpCodes.Callvirt, AppendMethod); //Call Append
}
generator.Emit(OpCodes.Ldloc, sb);
generator.Emit(OpCodes.Ret); //return pointer to sb
dynAccessor.WriteHandler = method.CreateDelegate(typeof(Write)) as Write;
return dynAccessor;
}
有什么想法吗? 提前致谢 :)
I'm trying to generate code that takes a StringBuilder, and writes the values of all the properties in a class to a string. I've got the following, but I'm currently getting a "Invalid method token" in the following code:
public static DynamicAccessor<T> CreateWriter(T target) //Target class to *serialize*
{
DynamicAccessor<T> dynAccessor = new DynamicAccessor<T>();
MethodInfo AppendMethod = typeof(StringBuilder).GetMethod("Append", new[] { typeof(Object) }); //Append method of Stringbuilder
var method = new DynamicMethod("ClassWriter", typeof(StringBuilder), new[] { typeof(T) }, typeof(T), true);
var generator = method.GetILGenerator();
LocalBuilder sb = generator.DeclareLocal(typeof(StringBuilder)); //sb pointer
generator.Emit(OpCodes.Newobj, typeof(StringBuilder)); //make our string builder
generator.Emit(OpCodes.Stloc, sb); //make a pointer to our new sb
//iterate through all the instance of T's props and sb.Append their values.
PropertyInfo[] props = typeof(T).GetProperties();
foreach (var info in props)
{
generator.Emit(OpCodes.Callvirt, info.GetGetMethod()); //call the Getter
generator.Emit(OpCodes.Ldloc, sb); //load the sb pointer
generator.Emit(OpCodes.Callvirt, AppendMethod); //Call Append
}
generator.Emit(OpCodes.Ldloc, sb);
generator.Emit(OpCodes.Ret); //return pointer to sb
dynAccessor.WriteHandler = method.CreateDelegate(typeof(Write)) as Write;
return dynAccessor;
}
Any ideas?
Thanks in advance :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
任何值类型的属性(
int
等)都需要装箱;或者您将需要使用不同的Append
重载。另外:
StringBuilder.Append
是一个流畅的API;您要么需要弹出该值,要么重新使用它:(但就我个人而言,我会返回一个
字符串
,但是“meh”)就像所以:
这生成等价于:
Any properties that are value-types (
int
etc) will need boxing; or you will need to use a differentAppend
overload.Also:
StringBuilder.Append
is a fluent API; you either need to pop the value, or re-use it:(personally, though, I'd return a
string
, but "meh")Like so:
This generates the equivalent to: