LINQ 扩展在 CSharpCodeProvider 中不可用
LINQ Extensions not available inside CSharpCodeProvider
我有一个 .NET 应用程序,它可以采用用 C# 编写的脚本并在内部执行它。脚本由下面列出的 class 解析,然后编译。我发现每当我尝试在编译的 C# 脚本中使用 System.Xml.Linq
时,我都会遇到编译错误,我不确定为什么。
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.Linq
和 System.Xml.Linq
,但编译器似乎无法找到它们。
这是我尝试编译的一个 C# 脚本示例,它使用了 LINQ 扩展。
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.Xml
和 System.Xml.Linq
。我还在构造函数中添加了编译器版本,但我仍然得到同样的错误。
CSharpCodeProvider(new Dictionary<String, String> { { "CompilerVersion", "v4.6.1" } })
在搜索相关错误后,我找到了解决方案。我需要添加 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
的引用,因为我假设它在创建编译器实例时默认被引用,但我猜不是。
我有一个 .NET 应用程序,它可以采用用 C# 编写的脚本并在内部执行它。脚本由下面列出的 class 解析,然后编译。我发现每当我尝试在编译的 C# 脚本中使用 System.Xml.Linq
时,我都会遇到编译错误,我不确定为什么。
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.Linq
和 System.Xml.Linq
,但编译器似乎无法找到它们。
这是我尝试编译的一个 C# 脚本示例,它使用了 LINQ 扩展。
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.Xml
和 System.Xml.Linq
。我还在构造函数中添加了编译器版本,但我仍然得到同样的错误。
CSharpCodeProvider(new Dictionary<String, String> { { "CompilerVersion", "v4.6.1" } })
在搜索相关错误后,我找到了解决方案。我需要添加 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
的引用,因为我假设它在创建编译器实例时默认被引用,但我猜不是。