gpt4 book ai didi

c# - 如何在 .NET Core 中发出类型

转载 作者:IT王子 更新时间:2023-10-29 04:12:31 27 4
gpt4 key购买 nike

在 C# 中,如何使用 .NET Core 在运行时发出新类型?我能找到的所有 .NET 6 示例似乎都不适用于 .NET Core(它们都以获取当前的 AppDomain 开始,它不再存在于 .NET Core 中)。

如果可能的话,我希望看到一个涉及创建类型并向该类型添加属性的示例。

最佳答案

这是一篇关于在 .NET 4 中创建动态类型的帖子。

How to dynamically create a class in C#?

在接受的答案中只是 AppDomain 的一种使用。

AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run);

这是另一篇关于替换 .NET 核心中的 DefineDynamicAssembly 函数的 SO 帖子。

Is there any replace of AssemblyBuilder.DefineDynamicAssembly in .NET Core?

这里是:

AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(Guid.NewGuid().ToString()),AssemblyBuilderAccess.Run);

"System.Reflection.Emit": "4.0.1" 中 nuget。

另外,TypeBuilder 也有区别。 CreateType 函数不再存在,我们应该使用 CreateTypeInfo 创建类型。是的,它又来自 SO 帖子。

CreateType missing from TypeBuilder. How to port this?

这是创建类型并向类型添加属性的工作修改示例(针对 .NET 核心)。

using System;
using System.Collections.Generic;
using System.Reflection.Emit;
using System.Reflection;

namespace ConsoleApp1
{
public class FieldDescriptor
{
public FieldDescriptor(string fieldName, Type fieldType)
{
FieldName = fieldName;
FieldType = fieldType;
}
public string FieldName { get; }
public Type FieldType { get; }
}

public static class MyTypeBuilder
{
public static object CreateNewObject()
{
var myTypeInfo = CompileResultTypeInfo();
var myType = myTypeInfo.AsType();
var myObject = Activator.CreateInstance(myType);

return myObject;
}

public static TypeInfo CompileResultTypeInfo()
{
TypeBuilder tb = GetTypeBuilder();
ConstructorBuilder constructor = tb.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);

var yourListOfFields = new List<FieldDescriptor>()
{
new FieldDescriptor("YourProp1",typeof(string)),
new FieldDescriptor("YourProp2", typeof(int))
};
foreach (var field in yourListOfFields)
CreateProperty(tb, field.FieldName, field.FieldType);

TypeInfo objectTypeInfo = tb.CreateTypeInfo();
return objectTypeInfo;
}

private static TypeBuilder GetTypeBuilder()
{
var typeSignature = "MyDynamicType";
var an = new AssemblyName(typeSignature);
var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(Guid.NewGuid().ToString()), AssemblyBuilderAccess.Run);
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule");
TypeBuilder tb = moduleBuilder.DefineType(typeSignature,
TypeAttributes.Public |
TypeAttributes.Class |
TypeAttributes.AutoClass |
TypeAttributes.AnsiClass |
TypeAttributes.BeforeFieldInit |
TypeAttributes.AutoLayout,
null);
return tb;
}

private static void CreateProperty(TypeBuilder tb, string propertyName, Type propertyType)
{
FieldBuilder fieldBuilder = tb.DefineField("_" + propertyName, propertyType, FieldAttributes.Private);

PropertyBuilder propertyBuilder = tb.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, null);
MethodBuilder getPropMthdBldr = tb.DefineMethod("get_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, propertyType, Type.EmptyTypes);
ILGenerator getIl = getPropMthdBldr.GetILGenerator();

getIl.Emit(OpCodes.Ldarg_0);
getIl.Emit(OpCodes.Ldfld, fieldBuilder);
getIl.Emit(OpCodes.Ret);

MethodBuilder setPropMthdBldr =
tb.DefineMethod("set_" + propertyName,
MethodAttributes.Public |
MethodAttributes.SpecialName |
MethodAttributes.HideBySig,
null, new[] { propertyType });

ILGenerator setIl = setPropMthdBldr.GetILGenerator();
Label modifyProperty = setIl.DefineLabel();
Label exitSet = setIl.DefineLabel();

setIl.MarkLabel(modifyProperty);
setIl.Emit(OpCodes.Ldarg_0);
setIl.Emit(OpCodes.Ldarg_1);
setIl.Emit(OpCodes.Stfld, fieldBuilder);

setIl.Emit(OpCodes.Nop);
setIl.MarkLabel(exitSet);
setIl.Emit(OpCodes.Ret);

propertyBuilder.SetGetMethod(getPropMthdBldr);
propertyBuilder.SetSetMethod(setPropMthdBldr);
}
}
}

关于c# - 如何在 .NET Core 中发出类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41784393/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com