【发布时间】:2010-09-05 08:28:32
【问题描述】:
启用 LINQ 的应用能否在仅安装了 .NET 2.0 运行时的机器上运行?
理论上,LINQ 只不过是语法糖,生成的 IL 代码应该与 .NET 2.0 中的代码相同。
如何在不使用 .NET 3.5 库的情况下编写 LINQ?它会在 .NET 2.0 上运行吗?
【问题讨论】:
标签: .net linq .net-3.5 .net-2.0 clr
启用 LINQ 的应用能否在仅安装了 .NET 2.0 运行时的机器上运行?
理论上,LINQ 只不过是语法糖,生成的 IL 代码应该与 .NET 2.0 中的代码相同。
如何在不使用 .NET 3.5 库的情况下编写 LINQ?它会在 .NET 2.0 上运行吗?
【问题讨论】:
标签: .net linq .net-3.5 .net-2.0 clr
奇怪的是没有人提到LINQBridge。这个很棒的小项目是将 LINQ(IEnumerable,但没有 IQueryable)及其依赖项(Func、Action 等)向后移植到 .NET 2.0。并且:
如果您的项目引用 LINQBridge 在编译期间,它将绑定 到 LINQBridge 的查询运算符;如果它 期间引用 System.Core 编译,然后它将绑定到 Framework 3.5 的查询运算符。
【讨论】:
有一些“黑客”涉及使用 3.5 框架中的 System.Core.dll 使其与 .net 2.0 一起运行,但我个人不希望使用这种有点不稳定的基础。
- 创建一个新的控制台应用程序
- 仅保留 System 和 System.Core 作为引用的程序集
- 将 System.Core 的 Copy Local 设置为 true,因为它在 .NET 2.0 中不存在
- 在 Main 方法中使用 LINQ 查询。例如下面的那个。
- 构建
- 将所有 bin 输出复制到仅安装了 .NET 2.0 的机器上
- 运行
(需要 .net 2.0 SP1,我不知道捆绑 System.Core.dll 是否违反 EULA)
【讨论】:
理论上是的,只要您分发 LINQ 特定程序集和任何依赖项。然而,这违反了微软的许可。 Scott Hanselman 写了一篇关于 Deploying ASP.NET MVC on ASP.NET 2.0 的博客文章,这与您想要做的事情相似。
【讨论】:
您可以使用来自 mono(.NET for Linux)的 LINQ 源来让 LINQ 在 .NET 2.0 上运行。
IEnumerable<T> : yes
IQueryable<T> : yes
LINQ to XML : has been working in the trunk, but due to further additions, the trunk doesn't compile anymore
这里有人做过:
LINQ for .NET 2.0
【讨论】:
简答:
IEnumerable<T>)IQueryable<T>)请参阅this question,了解 .Net 3.5 功能在从 VS2008 面向 .Net 2.0 时自动或轻松可用的功能。
基本上,任何只是“语法糖”和新编译器(C# 3.0、VB 9.0)作为 2.0 兼容的 IL 发出的东西都可以工作。这包括 LINQ 使用的许多功能,例如匿名类、作为匿名委托的 lambda、自动属性、对象初始值设定项和集合初始值设定项。
某些 LINQ 功能使用新的 3.5 程序集(例如 System.Core.dll)中的类、接口、委托和扩展方法。重新分发这些程序集是违反许可证的,但可以重新实现它们。使用扩展方法只需要声明一个空的System.Runtime.CompilerServices.ExtensionAttribute。 LINQ to Objects 依赖于IEnumerable<T> 扩展和几个委托声明(Action<T> 和Func<T> 系列),并已在LINQBridge 中实现(如mausch 所述)。 LINQ to XML 和 LINQ to DataSets 依赖于 LINQ to Objects,我猜这也可以在 .Net 2.0 中实现,但我还没有看到这样做。
LINQ to SQL 和 LINQ to Entities 需要许多新类(DataContext/ObjectContext、大量属性、EntitySet<T>、EntityRef<T>、Link<T>、IQueryable<T> 等)和表达式树,这,即使以某种方式重新实现,也可能至少需要 .Net 2.0 SP1 才能工作。
【讨论】:
我不确定 C#。
不过,我确实知道,只要您使用 VS 2008 编译器以 2.0 框架为目标,就可以编写不使用 3.5 库的 VB LINNQ 代码。
但是,您必须自己实现一些 LINQ 方法。
LINQ 使用语法转换将查询转换为可执行代码。基本上,它将采用如下代码:
dim q = from x in xs where x > 2 select x*4;
并将其转换为如下代码:
dim q = xs.where(function(x) x > 2).select(function(x) x * 4);
对于 3.5 框架附带的 LINQ 功能,这些方法在 IEnumerable 或 IQueryable 上作为扩展方法实现(还有一堆方法也适用于数据集)。
默认的 IEnumerable 扩展方法在 System.Linq.Enumerable 中定义,如下所示:
<Extension()>
public function Select(of T, R)(source as IEnumerable(of T), transform as Func(of T, R)) as IEnumerable(of R)
'do the transformation...
end function
IQueryable 扩展方法将表达式树作为参数,而不是 lambda。它们看起来像这样:
<Extension()>
public function Select(of T, R)(source as IQueryable<T>, transform as Expression(of Func(of T, R))
'build a composite IQueryable that contains the expression tree for the transformation
end function
表达式树版本使您能够获得提供给子句的表达式的树表示,然后可用于生成 SQL 代码(或您想要的任何其他内容)。
您可能会在大约一天左右的时间内创建自己的 LINQ to 对象版本。一切都很简单。
如果你想使用 LINQ,那么事情会有点困难。
【讨论】:
不,因为虽然您认为 LINQ 实际上只是语法糖,但它实际上大量使用了表达式树——.NET 2.0 中没有这个功能。
也就是说 .NET 3.5 只是建立在 .NET 2.0 之上,这就是 IL 看起来没有“不同”或“特殊”的原因。
我看不出为什么您不应该只安装 .NET 3.5 Framework。 .NET 2.0 的所有东西都可以正常工作,保证 :)
【讨论】:
.NET 2.0。是的。说真的,我们做到了。
据我所知,LINQ 库仅在框架 3.0 之后才可用。 如果你想在 framework 2.0 中使用类似的东西,你需要自己重写它:) 或者找一个类似的第三方库。我只找到了一点信息here,但也没有说服我。
【讨论】: