C# 如何生成程序集并将其保存。。?

C# 如何生成程序集并将其保存。。?,c#,C#,有许多c#代码片段演示如何构建.net程序集 代码已成功运行,但问题是保存的程序集不包含生成的代码。-即使我已经为AssemblyBuilder设置了RunAndSave属性 有谁能告诉我如何正确构建和保存具有生成的类、方法等的程序集 谢谢 以下是我在演示中使用的一些代码。这对于一个简单的例子来说有点过分,但它是有效的。保存在BuildGenericType方法中完成 using System; using System.Collections.Generic; using System.Lin

有许多c#代码片段演示如何构建.net程序集

代码已成功运行,但问题是保存的程序集不包含生成的代码。-即使我已经为AssemblyBuilder设置了RunAndSave属性

有谁能告诉我如何正确构建和保存具有生成的类、方法等的程序集


谢谢

以下是我在演示中使用的一些代码。这对于一个简单的例子来说有点过分,但它是有效的。保存在BuildGenericType方法中完成

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

namespace ReflectionEmit
{
    class Program
    {
        delegate int DoMath(int value);

        static DoMath mathFunc;

        static void Main(string[] args)
        {
            CreateCode(27, true);
            CreateCode(27, false);

            BuildGenericType();

            Console.ReadKey();
        }

        private static void CreateCode(int value, bool square)
        {
            mathFunc = (DoMath)BuildMethod(square).CreateDelegate(typeof(DoMath));
            int result = mathFunc(value);

            Console.WriteLine("Result for {0} was {1}", value, result );

        }

        private static DynamicMethod BuildMethod(bool square)
        {
            Type[] methodArgs = { typeof(int) };
            DynamicMethod mthMeth = new DynamicMethod(
                "Square",
                typeof(int),
                methodArgs,
                typeof(ReflectionEmit.Program).Module);

            ILGenerator il = mthMeth.GetILGenerator();

            if (square)
            {
                il.Emit(OpCodes.Ldarg_0); //Loads argument at index 0 into the evaluation stack
                il.Emit(OpCodes.Conv_I8); //Converts the value on top of the evaluation stack to int64
                il.Emit(OpCodes.Dup); //Copies the top most value on the evaluation stack, then pushes it to the top
                il.Emit(OpCodes.Mul); //Multiplies two values then pushes result to top of evaluation stack
                il.Emit(OpCodes.Ret); //Returns from the current method, pushing a return value (if present) from the callee's evaluation stack onto the caller's evaluation stack. 
            }
            else
            {
                il.Emit(OpCodes.Ldarg_0); //Loads argument at index 0 into the evaluation stack
                il.Emit(OpCodes.Conv_I8); //Converts the value on top of the evaluation stack to int64
                il.Emit(OpCodes.Dup); //Copies the top most value on the evaluation stack, then pushes it to the top
                il.Emit(OpCodes.Add); //Adds two values then pushes result to top of evaluation stack
                il.Emit(OpCodes.Ret); //Returns from the current method, pushing a return value (if present) from the callee's evaluation stack onto the caller's evaluation stack.
            }

            return mthMeth;
        }

        private static void BuildGenericType()
        {
            //Define assembly
            AppDomain dom = AppDomain.CurrentDomain;
            AssemblyName asmName = new AssemblyName("domath");
            AssemblyBuilder asm = dom.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave);

            //Define a dynamic module
            ModuleBuilder mod = asm.DefineDynamicModule(asmName.Name, asmName.Name + ".dll");

            //Define a class
            TypeBuilder asmType = mod.DefineType("OurClass", TypeAttributes.Public);

            //Define the generic type parameters
            string[] typeNames = { "TFirst", "TSecond" };
            GenericTypeParameterBuilder[] genTypes = asmType.DefineGenericParameters(typeNames);

            GenericTypeParameterBuilder TFirst = genTypes[0];
            GenericTypeParameterBuilder TSecond = genTypes[1];

            //Define generic constraints
            TFirst.SetGenericParameterAttributes(GenericParameterAttributes.DefaultConstructorConstraint | GenericParameterAttributes.ReferenceTypeConstraint);
            TSecond.SetBaseTypeConstraint(typeof(SomeBaseClass));

            Type[] interfaceTypes = {typeof(InterfaceA), typeof(InterfaceB) };
            TSecond.SetInterfaceConstraints(interfaceTypes);

            //Define a field
            FieldBuilder fld1 = asmType.DefineField("Field1", TFirst, FieldAttributes.Private);

            //Define method
            Type listOf = typeof(List<>);
            Type listOfTFirst = listOf.MakeGenericType(TFirst);
            Type[] paramTypes = { TFirst.MakeArrayType() };

            MethodBuilder asmMethod = asmType.DefineMethod("SomeMethod", MethodAttributes.Public | MethodAttributes.Static, listOfTFirst, paramTypes);

            //Define Method Body
            ILGenerator il = asmMethod.GetILGenerator();

            Type ienumOf = typeof(IEnumerable<>);
            Type tFromListOf = listOf.GetGenericArguments()[0];
            Type ienumOfT = ienumOf.MakeGenericType(tFromListOf);
            Type[] ctorArgs = { ienumOfT };

            ConstructorInfo ctorPrep = listOf.GetConstructor(ctorArgs);
            ConstructorInfo ctor = TypeBuilder.GetConstructor(listOfTFirst, ctorPrep);

            il.Emit(OpCodes.Ldarg_0); //Loads the argument at index 0 onto the evaluation stack.
            il.Emit(OpCodes.Newobj, ctor); //Creates a new object or a new instance of a value type, pushing an object reference (type O) onto the evaluation stack.
            il.Emit(OpCodes.Ret); //Returns from the current method, pushing a return value (if present) from the callee's evaluation stack onto the caller's evaluation stack.

            //Create type and save file
            Type finished = asmType.CreateType();
            asm.Save(asmName.Name + ".dll");



        }
    }

    public interface InterfaceA { }
    public interface InterfaceB { }

    public class SomeBaseClass
    {

    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Reflection.Emit;
运用系统反思;
名称空间反射mit
{
班级计划
{
委托int域(int值);
静态DoMath-mathFunc;
静态void Main(字符串[]参数)
{
CreateCode(27,true);
CreateCode(27,false);
BuildGenericType();
Console.ReadKey();
}
私有静态void CreateCode(int值,布尔平方)
{
mathFunc=(DoMath)BuildMethod(square).CreateDelegate(typeof(DoMath));
int result=mathFunc(值);
WriteLine({0}的结果为{1}),值,结果);
}
私有静态动态方法BuildMethod(布尔平方)
{
Type[]methodArgs={typeof(int)};
DynamicMethod mthMeth=新的DynamicMethod(
“广场”,
类型(int),
方法论,
类型(ReflectionMit.Program).Module);
ILGenerator il=mthMeth.GetILGenerator();
if(方形)
{
il.Emit(OpCodes.Ldarg_0);//将索引0处的参数加载到计算堆栈中
il.Emit(OpCodes.Conv_I8);//将求值堆栈顶部的值转换为int64
il.Emit(OpCodes.Dup);//复制求值堆栈上最顶端的值,然后将其推送到顶端
il.Emit(OpCodes.Mul);//将两个值相乘,然后将结果推送到计算堆栈的顶部
il.Emit(OpCodes.Ret);//从当前方法返回,将返回值(如果存在)从被调用方的计算堆栈推送到调用方的计算堆栈上。
}
其他的
{
il.Emit(OpCodes.Ldarg_0);//将索引0处的参数加载到计算堆栈中
il.Emit(OpCodes.Conv_I8);//将求值堆栈顶部的值转换为int64
il.Emit(OpCodes.Dup);//复制求值堆栈上最顶端的值,然后将其推送到顶端
il.Emit(OpCodes.Add);//添加两个值,然后将结果推送到求值堆栈的顶部
il.Emit(OpCodes.Ret);//从当前方法返回,将返回值(如果存在)从被调用方的计算堆栈推送到调用方的计算堆栈上。
}
返回mthMeth;
}
私有静态void BuildGenericType()
{
//定义程序集
AppDomain dom=AppDomain.CurrentDomain;
AssemblyName asmName=新的AssemblyName(“domath”);
AssemblyBuilder asm=dom.DefinedDynamicAssembly(asmName,AssemblyBuilderAccess.RunAndSave);
//定义一个动态模块
ModuleBuilder mod=asm.definedDynamicModule(asmName.Name,asmName.Name+“.dll”);
//定义一个类
TypeBuilder asmType=mod.DefineType(“我们的类”,TypeAttributes.Public);
//定义泛型类型参数
字符串[]typeNames={“TFirst”,“TSecond”};
GenericTypeParameterBuilder[]genTypes=asmType.DefineGenericParameters(typeNames);
GenericTypeParameterBuilder TFirst=genTypes[0];
GenericTypeParameterBuilder TSecond=genTypes[1];
//定义泛型约束
t第一个.SetGenericParameterAttributes(GenericParameterAttributes.DefaultConstructorConstraint | GenericParameterAttributes.ReferenceTypeConstraint);
TSecond.SetBaseTypeConstraint(typeof(SomeBaseClass));
类型[]接口类型={typeof(interfaceea),typeof(interfaceeb)};
t第二个设置接口约束(interfaceTypes);
//定义字段
FieldBuilder fld1=asmType.DefineField(“Field1”,TFirst,FieldAttributes.Private);
//定义方法
类型listOf=类型(列表);
类型ListofFirst=listOf.MakeGenericType(TFirst);
Type[]paramTypes={TFirst.MakeArrayType()};
MethodBuilder asmMethod=asmType.DefineMethod(“SomeMethod”,MethodAttributes.Public | MethodAttributes.Static,ListofFirst,paramTypes);
//定义方法体
ILGenerator il=asmMethod.GetILGenerator();
类型ienumOf=类型(IEnumerable);
类型tFromListOf=listOf.GetGenericArguments()[0];
类型ienumOfT=ienumOf.MakeGenericType(tFromListOf);
类型[]ctorArgs={ienumOfT};
ConstructorInfo-ctorPrep=listOf.GetConstructor(ctorArgs);
ConstructorInfo-ctor=TypeBuilder.GetConstructor(ListofFirst,ctorPrep);
il.Emit(OpCodes.Ldarg_0);//将索引0处的参数加载到计算堆栈中。
Emit(OpCodes.Newobj,ctor);//创建一个新对象或值类型的新实例,将对象引用(类型O)推送到计算堆栈上。
il.Emit(OpCodes.Ret);//从当前方法返回,将返回值(如果存在)从被调用方的计算堆栈推送到调用方的计算堆栈上。
//创建类型并保存文件
类型finished=asmType.CreateType();
asm.Save(asmName.Name+“.dll”);
}
}
公共接口a{}
公共接口B{}
公共类SomeBaseClass
{
}
}
或者,你可以试试Rosy
AssemblyName aName = new AssemblyName("DynamicAssemblyExample");
AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly(aName, AssemblyBuilderAccess.RunAndSave); // Include Save access!

ModuleBuilder mb = ab.DefineDynamicModule(aName.Name, aName.Name + ".dll"); // *Same name here ..*

// ... (Other code building types, methods etc.)

ab.Save(aName.Name + ".dll"); // *... and here*