1

我有一个 .NET 应用程序,它可以采用 C# 编写的脚本并在内部执行它。脚本由下面列出的类解析,然后编译。我发现每当我尝试System.Xml.Linq在已编译的 C# 脚本中使用时,都会出现编译错误,我不知道为什么。

public static void CreateFunction(string scriptCode, BO.ObjectBO obj)
{
    CSharpCodeProvider provider = new CSharpCodeProvider();
    CompilerParameters options = new CompilerParameters();
    options.ReferencedAssemblies.Add("System.Data.dll");
    options.ReferencedAssemblies.Add("System.dll");
    options.ReferencedAssemblies.Add("System.Xml.dll");
    options.ReferencedAssemblies.Add("System.Linq.dll");
    options.ReferencedAssemblies.Add("System.Xml.Linq.dll");

    options.GenerateExecutable = false;
    options.GenerateInMemory = true;
    CompilerResults results = provider.CompileAssemblyFromSource(options, scriptCode);

    _errors = results.Errors;

    if (results.Errors.HasErrors)
    {
        DataTable errorTable = BO.DataTableBO.ErrorTable();
        foreach(CompilerError err in results.Errors)
        {
           DataRow dr = errorTable.NewRow();
           dr["ErrorMessage"] = "Line "+ err.ErrorNumber.ToString() + " " + err.ErrorText;
           errorTable.Rows.Add(dr);
         }
        return;
    }

    Type binaryFunction = results.CompiledAssembly.GetType("UserFunctions.BinaryFunction");

    _methodInfo = binaryFunction.GetMethod("Function");
}

这是我尝试运行LINQ extensions在编译器内部使用的脚本时收到的错误消息。

'System.Collections.Generic.IEnumerable<System.Xml.Linq.XElement>' does not contain a definition for 'Select' and no extension method 'Select' accepting a first argument of type 'System.Collections.Generic.IEnumerable<System.Xml.Linq.XElement>' could be found (are you missing a using directive or an assembly reference?)

有谁看到我可能做错了什么?我试图包含System.LinqSystem.Xml.Linq但编译器似乎无法找到它们。

这是我正在尝试编译的使用 LINQ 扩展的示例 C# 脚本。

using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Xml.Linq;

namespace CompilerTest
{
  public class BinaryFunction
  {
    public static void Function()
    {
      string xmlData = @"<data>
                          <clients>
                            <client>
                              <clientId>1</clientId>
                              <clientName>Dell</clientName>
                            </client>
                            <client>
                              <clientId>2</clientId>
                              <clientName>Apple</clientName>
                            </client>
                          </clients>
                        </data>";

      XDocument xDoc = XDocument.Parse(xmlData);

      List<string> results = xDoc.Descendants("data")
                            .Descendants("client")
                            .Select(x => x.Element("clientName").Value)
                            .ToList<string>();

    }
  }
}

更新:我确认 GAC 中有以下程序集。System.XmlSystem.Xml.Linq。我还将编译器版本添加到构造函数中,但仍然出现相同的错误。

  CSharpCodeProvider(new Dictionary<String, String> { { "CompilerVersion", "v4.6.1" } })
4

1 回答 1

3

搜索相关错误后,我找到了解决方案。我需要将 System.Core 添加为引用程序集。

options.ReferencedAssemblies.Add("System.Core.dll");

一旦我这样做了,就使用了 LINQ 程序集,并且我能够使用 LINQ 扩展。所以要清楚我的新代码是

CSharpCodeProvider provider = new CSharpCodeProvider();
CompilerParameters options = new CompilerParameters();
options.ReferencedAssemblies.Add("System.Data.dll");
options.ReferencedAssemblies.Add("System.dll");
options.ReferencedAssemblies.Add("System.Xml.dll");
options.ReferencedAssemblies.Add("System.Linq.dll");
options.ReferencedAssemblies.Add("System.Xml.Linq.dll");
options.ReferencedAssemblies.Add("System.Core.dll");

我不确定为什么System.Core.dll需要添加对的引用,因为我假设在创建编译器实例时默认引用它,但我猜不是。

于 2018-02-19T19:48:18.333 回答