public static string InvokeStr(this MethodDef method, object rva) { var builder = new StringBuilder(); //string ctx = method.TypeArgumentStr(); if (method.HasGenericParameters) { builder.Append("<"); builder.Append(string.Join(", ", method.GenericParameters.Select(g => $"{g.Name.String.Parseable()}"))); builder.Append("> "); } else if (method.DeclaringType.GenericParameters.Count > 0) { builder.Append("<"); builder.Append(string.Join(", ", method.DeclaringType.GenericParameters.Select(g => $"{g.Name.String.Parseable()}"))); builder.Append("> "); } string ctx = builder.ToString(); if (true || ctx.Length <= 2) { ctx = null; } if (method.IsVirtual && !method.DeclaringType.IsValueType) { return ($"{{ const VirtualInvokeData& Data = this->ClassPtr->VTable[{method.GetSlot()}]; return reinterpret_cast<{method.VirtualTypeDefinitionStr(ctx)}>(Data.methodPtr)({string.Join(", ", method.Parameters.Select((p, i) => $"{(p.IsHiddenThisParameter ? "this" : ((p.Name.Length > 0 ? p.Name.Parseable() : $"a{i}") + "_"))}").Append("Data.method"))}); }}");