[英]Stringbuilder in CIL (MSIL)
I'm trying to generate code that takes a StringBuilder, and writes the values of all the properties in a class to a string. 我正在尝试生成带有StringBuilder的代码,并将类中所有属性的值写入字符串。 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 :) 提前致谢 :)
Any properties that are value-types ( int
etc) will need boxing; 任何属于value-types( int
等)的属性都需要装箱; or you will need to use a different Append
overload. 或者你需要使用不同的Append
重载。
Also: 也:
StringBuilder.Append
is a fluent API; StringBuilder.Append
是一个流畅的API; you either need to pop the value, or re-use it: 您需要弹出值,或重新使用它: (personally, though, I'd return a string
, but "meh") (就个人而言,我会返回一个string
,但“meh”)
Like so: 像这样:
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();
generator.Emit(OpCodes.Newobj, typeof(StringBuilder).GetConstructor(Type.EmptyTypes)); //make our string builder
//iterate through all the instance of T's props and sb.Append their values.
PropertyInfo[] props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (var info in props)
{
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Callvirt, info.GetGetMethod()); //call the Getter
if (info.PropertyType.IsValueType)
{
generator.Emit(OpCodes.Box, info.PropertyType);
}
generator.Emit(OpCodes.Callvirt, AppendMethod); //Call Append
}
generator.Emit(OpCodes.Ret); //return pointer to sb
This generates the equivalent to: 这会产生相当于:
StringBuilder ClassWriter(T obj) {
return new StringBuilder.Append((object)obj.Foo).Append((object)obj.Bar)
.Append((object)obj.Blip).Append((object)obj.Blap);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.