请教 EMIT 其他信息: 操作可能会破坏运行时稳定性。

dy2017 2019-05-31 02:48:04

struct EntityPropInfo
{
public readonly string PropertyName;
public readonly Type Type;
public readonly MethodInfo GetMethod;

public EntityPropInfo(PropertyInfo prop)
{
PropertyName = prop.Name;
Type = prop.PropertyType;
GetMethod = prop.GetGetMethod(false);
}
}

private Func<T, List<object>> GetDelegate(List<EntityPropInfo> lepis)
{
Type type = typeof(T);
var dm = new DynamicMethod("getValue1", typeof(List<object>), new Type[] { type }, true);
ILGenerator il = dm.GetILGenerator();

LocalBuilder list = il.DeclareLocal(typeof(List<object>));
il.Emit(OpCodes.Newobj, typeof(List<object>).GetConstructor(Type.EmptyTypes));
il.Emit(OpCodes.Stloc_S, list);

for (int i = 0; i < lepis.Count; ++i)
{
LocalBuilder obj = il.DeclareLocal(lepis[i].Type);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Stloc, obj);

il.Emit(OpCodes.Call, lepis[i].GetMethod);
if (lepis[i].Type.IsValueType)
{
il.Emit(OpCodes.Box, lepis[i].Type);
}
il.Emit(OpCodes.Ldloc, list);
il.Emit(OpCodes.Ldloc, obj);
il.Emit(OpCodes.Callvirt, typeof(List<object>).GetMethod("Add"));
}

il.Emit(OpCodes.Ldloc_S, list);
il.Emit(OpCodes.Ret);
return dm.CreateDelegate(typeof(Func<T, List<object>>)) as Func<T, List<object>>;
}

private void GetProperties()
{
if (leps == null)
leps = new List<EntityPropInfo>();
leps.Clear();

if (lgs == null)
lgs = new List<Func<T, object>>();
lgs.Clear();

foreach (var prop in typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public))
{
if (prop.GetIndexParameters().Length > 0)
continue;
var getMethod = prop.GetGetMethod(false);
if (getMethod == null)
continue;
EntityPropInfo epi = new EntityPropInfo(prop);
leps.Add(epi);
lgs.Add(Getter(epi));
}
EntityDelegate = GetDelegate(leps);

}

private Func<T, List<object>> EntityDelegate


各位高手看看, 其他信息: 操作可能会破坏运行时稳定性。
...全文
112 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
dy2017 2019-06-19
  • 打赏
  • 举报
回复
完整代码,https://blog.csdn.net/dy2017/article/details/92833191
dy2017 2019-05-31
  • 打赏
  • 举报
回复
引用 5 楼 stherix 的回复:
仔细看了下,是IL写错了,运行肯定出错

for (int i = 0; i < lepis.Count; ++i)
{               
    il.Emit(OpCodes.Ldloc, list);
    il.Emit(OpCodes.Ldarg_0);
    il.Emit(OpCodes.Call, lepis[i].GetMethod);
    if (lepis[i].Type.IsValueType)
    {
        il.Emit(OpCodes.Box, lepis[i].Type);
    }
    il.Emit(OpCodes.Callvirt, typeof(List<object>).GetMethod("Add"));
}
,谢谢!谢谢!
stherix 2019-05-31
  • 打赏
  • 举报
回复
仔细看了下,是IL写错了,运行肯定出错

for (int i = 0; i < lepis.Count; ++i)
{               
    il.Emit(OpCodes.Ldloc, list);
    il.Emit(OpCodes.Ldarg_0);
    il.Emit(OpCodes.Call, lepis[i].GetMethod);
    if (lepis[i].Type.IsValueType)
    {
        il.Emit(OpCodes.Box, lepis[i].Type);
    }
    il.Emit(OpCodes.Callvirt, typeof(List<object>).GetMethod("Add"));
}
dy2017 2019-05-31
  • 打赏
  • 举报
回复
引用 3 楼 caozhy 的回复:
如果你就是调用Add,而不想用反射的话,可以用ExpressionTree,它比Emit简单
不只是调用Add ,这个地方一直调不通,需要实现orm
threenewbee 2019-05-31
  • 打赏
  • 举报
回复
如果你就是调用Add,而不想用反射的话,可以用ExpressionTree,它比Emit简单
dy2017 2019-05-31
  • 打赏
  • 举报
回复
引用 1 楼 stherix 的回复:
var dm = new DynamicMethod("getValue1", typeof(List<object>), new Type[] { type }, typeof(T) , true);
不成啊,提示 其他信息: 公共语言运行时检测到无效的程序。
stherix 2019-05-31
  • 打赏
  • 举报
回复
var dm = new DynamicMethod("getValue1", typeof(List<object>), new Type[] { type }, typeof(T) , true);

62,046

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧