C# 在C语言中执行文本文件中的代码行#

C# 在C语言中执行文本文件中的代码行#,c#,.net,file,text,C#,.net,File,Text,我有一个文本文件,看起来像: AssembleComponent Motor = new AssembleComponent; AssembleComponent Shaft = new AssembleComponent; ...... Motor.cost = 100; Motor.quantity = 100; Shaft.cost = 10; Shaft.quantity = 100; ...... 我希望在C#中执行这些代码行,以便将这些Motor.cost、Motor.quant

我有一个文本文件,看起来像:

AssembleComponent Motor = new AssembleComponent;
AssembleComponent Shaft = new AssembleComponent;
......

Motor.cost = 100;
Motor.quantity = 100;
Shaft.cost = 10;
Shaft.quantity = 100;
......
我希望在C#中执行这些代码行,以便将这些Motor.cost、Motor.quantity、Shaft.cost、Shaft.quantity变量存储在内存中,以便以后进行计算

要实现这一点,我可以做些什么?

您可以使用它动态编译代码

具体来说,请看。

您可以使用它动态编译代码


具体来看。

您有两个主要选择:

  • 展开文本,直到它成为有效的C#代码,编译并执行它
  • 解析它并自己执行(即解释它)

  • 您有两个主要选择:

  • 展开文本,直到它成为有效的C#代码,编译并执行它
  • 解析它并自己执行(即解释它)

  • 如果只是关于数据,不要使用平面文本文件,而是XML


    您可以将XML反序列化为对象,并对其执行必要的操作。

    如果只是关于数据,请不要使用平面文本文件,而是使用XML


    您可以将XML反序列化为对象,并对其执行必要的操作。

    将其存储为XML

    
    
    假设你有这个定义

    公共类AssembleComponent
    {
    公共十进制成本{get;set;}
    公共整数数量{get;set;}
    }
    
    像这样装

    AssembleComponent motor = components["Motor"];
    AssembleComponent shaft = components["Shaft"];
    
    var components=newdictionary();
    XDocument doc=XDocument.Load(@“C:\Users\Oli\Desktop\components.xml”);
    foreach(doc.Root.subjections()中的XElement el){
    字符串名称=el.Attribute(“name”).Value;
    十进制成本=decimal.Parse(el.Attribute(“成本”).Value);
    int数量=Int32.Parse(el.Attribute(“数量”).Value);
    Add(名称,新的AssembleComponent{
    成本=成本,数量=数量
    });
    }
    

    然后可以像这样访问组件

    AssembleComponent motor = components["Motor"];
    AssembleComponent shaft = components["Shaft"];
    

    注意:通过在运行时调用编译器来动态创建变量名并不是很有用,因为您需要在编译时(或者如果愿意,在设计时)了解它们,才能对它们做一些有用的事情。因此,我将组件添加到字典中。这是一种动态创建“变量”的好方法。

    将其存储为XML

    
    
    假设你有这个定义

    公共类AssembleComponent
    {
    公共十进制成本{get;set;}
    公共整数数量{get;set;}
    }
    
    像这样装

    AssembleComponent motor = components["Motor"];
    AssembleComponent shaft = components["Shaft"];
    
    var components=newdictionary();
    XDocument doc=XDocument.Load(@“C:\Users\Oli\Desktop\components.xml”);
    foreach(doc.Root.subjections()中的XElement el){
    字符串名称=el.Attribute(“name”).Value;
    十进制成本=decimal.Parse(el.Attribute(“成本”).Value);
    int数量=Int32.Parse(el.Attribute(“数量”).Value);
    Add(名称,新的AssembleComponent{
    成本=成本,数量=数量
    });
    }
    

    然后可以像这样访问组件

    AssembleComponent motor = components["Motor"];
    AssembleComponent shaft = components["Shaft"];
    

    注意:通过在运行时调用编译器来动态创建变量名并不是很有用,因为您需要在编译时(或者如果愿意,在设计时)了解它们,才能对它们做一些有用的事情。因此,我将组件添加到字典中。这是一种动态创建“变量”的好方法。

    以下是我在过去使用过的一些代码,它们可以完成大部分您想要的功能,尽管您可能需要根据您的特定需要对其进行调整。简言之,它的功能如下:

    • 在该命名空间中创建临时命名空间和公共静态方法
    • 将代码编译到内存中的程序集
    • 提取已编译的方法并将其转换为委托
    • 执行委托
    在这一点上,它就像执行一个普通的静态方法,所以当你说你想把结果存储在内存中供以后使用时,你必须弄清楚它是如何工作的

    public void CompileAndExecute(string CodeBody)
    {
        // Create the compile unit
        CodeCompileUnit ccu = CreateCode(CodeBody);
    
        // Compile the code 
        CompilerParameters comp_params = new CompilerParameters();
        comp_params.GenerateExecutable = false;
        comp_params.GenerateInMemory = true;
        comp_params.TreatWarningsAsErrors = true;
        comp_results = code_provider.CompileAssemblyFromDom(comp_params, ccu);
    
        // CHECK COMPILATION RESULTS
        if (!comp_results.Errors.HasErrors)
        {
            Type output_class_type = comp_results.CompiledAssembly.GetType("TestNamespace.TestClass");
    
            if (output_class_type != null)    
            {    
                MethodInfo compiled_method = output_class_type.GetMethod("TestMethod", BindingFlags.Static | BindingFlags.Public);    
                if (compiled_method != null)    
                {    
                    Delgate created_delegate = Delegate.CreateDelegate(typeof(System.Windows.Forms.MethodInvoker), compiled_method);
                    if (created_delegate != null)
                    {
                        // Run the code
                        created_delegate.DynamicInvoke();
                    }
                }
            }
        }
        else
        {
            foreach (CompilerError error in comp_results.Errors)
            {
                // report the error
            }
        }
    }
    
    public CodeCompileUnit CreateCode(string CodeBody)
    {
        CodeNamespace code_namespace = new CodeNamespace("TestNamespace");
    
        // add the class to the namespace, add using statements
        CodeTypeDeclaration code_class = new CodeTypeDeclaration("TestClass");
        code_namespace.Types.Add(code_class);
        code_namespace.Imports.Add(new CodeNamespaceImport("System"));
    
        // set function details
        CodeMemberMethod method = new CodeMemberMethod();
        method.Attributes = MemberAttributes.Public | MemberAttributes.Static;
        method.ReturnType = new CodeTypeReference(typeof(void));
        method.Name = "TestMethod";
    
        // add the user typed code
        method.Statements.Add(new CodeSnippetExpression(CodeBody));
    
        // add the method to the class
        code_class.Members.Add(method);
    
        // create a CodeCompileUnit to pass to our compiler
        CodeCompileUnit ccu = new CodeCompileUnit();
        ccu.Namespaces.Add(code_namespace);
    
        return ccu;
    }
    

    这里有一些我在过去使用过的代码,它们可以满足您的大部分需求,尽管您可能需要根据您的具体需求进行调整。简言之,它的功能如下:

    • 在该命名空间中创建临时命名空间和公共静态方法
    • 将代码编译到内存中的程序集
    • 提取已编译的方法并将其转换为委托
    • 执行委托
    在这一点上,它就像执行一个普通的静态方法,所以当你说你想把结果存储在内存中供以后使用时,你必须弄清楚它是如何工作的

    public void CompileAndExecute(string CodeBody)
    {
        // Create the compile unit
        CodeCompileUnit ccu = CreateCode(CodeBody);
    
        // Compile the code 
        CompilerParameters comp_params = new CompilerParameters();
        comp_params.GenerateExecutable = false;
        comp_params.GenerateInMemory = true;
        comp_params.TreatWarningsAsErrors = true;
        comp_results = code_provider.CompileAssemblyFromDom(comp_params, ccu);
    
        // CHECK COMPILATION RESULTS
        if (!comp_results.Errors.HasErrors)
        {
            Type output_class_type = comp_results.CompiledAssembly.GetType("TestNamespace.TestClass");
    
            if (output_class_type != null)    
            {    
                MethodInfo compiled_method = output_class_type.GetMethod("TestMethod", BindingFlags.Static | BindingFlags.Public);    
                if (compiled_method != null)    
                {    
                    Delgate created_delegate = Delegate.CreateDelegate(typeof(System.Windows.Forms.MethodInvoker), compiled_method);
                    if (created_delegate != null)
                    {
                        // Run the code
                        created_delegate.DynamicInvoke();
                    }
                }
            }
        }
        else
        {
            foreach (CompilerError error in comp_results.Errors)
            {
                // report the error
            }
        }
    }
    
    public CodeCompileUnit CreateCode(string CodeBody)
    {
        CodeNamespace code_namespace = new CodeNamespace("TestNamespace");
    
        // add the class to the namespace, add using statements
        CodeTypeDeclaration code_class = new CodeTypeDeclaration("TestClass");
        code_namespace.Types.Add(code_class);
        code_namespace.Imports.Add(new CodeNamespaceImport("System"));
    
        // set function details
        CodeMemberMethod method = new CodeMemberMethod();
        method.Attributes = MemberAttributes.Public | MemberAttributes.Static;
        method.ReturnType = new CodeTypeReference(typeof(void));
        method.Name = "TestMethod";
    
        // add the user typed code
        method.Statements.Add(new CodeSnippetExpression(CodeBody));
    
        // add the method to the class
        code_class.Members.Add(method);
    
        // create a CodeCompileUnit to pass to our compiler
        CodeCompileUnit ccu = new CodeCompileUnit();
        ccu.Namespaces.Add(code_namespace);
    
        return ccu;
    }
    

    可能的重复:它不是真正的重复,因为问题可以在不执行文件中的任何代码行的情况下解决。相反,只有值存储在文件中,而不是代码中。可能的重复:它不是真正的重复,因为问题可以在不执行文件中的任何代码行的情况下解决。相反,文件中只存储值,而不是代码。感谢您的帮助。很抱歉没有及时接受你的回答,因为我不知道这个功能:D。谢谢你的帮助。很抱歉没有及时接受您的回答,因为我不知道这个函数:D。