用于向后移植新的 .NET Framework 功能的“兼容包”?
Posted
技术标签:
【中文标题】用于向后移植新的 .NET Framework 功能的“兼容包”?【英文标题】:"Compatibility Pack" for backporting new .NET Framework features? 【发布时间】:2011-03-28 14:32:25 【问题描述】:由于各种原因,我经常发现编写与 .NET framework 2.0 或 3.5 兼容或与 .NET Compact Framework 兼容的代码是可取的,但新的 .NET 中有许多“小”功能是一个问题旧框架或 Compact Framework 中不可用的框架。
例如,我发现扩展方法非常有用,但编译器为此依赖于System.Runtime.CompilerServices.ExtensionAttribute
。您可以轻松地自己定义此属性,然后在 .NET Framework 2.0(在 C# 3.0+ 下)中使用扩展方法。同样,手动定义像Tuple<T1,T2>
和Lazy<T>
这样的小.NET 4 类型也不是太难。顺便说一句,如果你想在.NET 2.0中使用LINQ,你可以使用LinqBridge。
现在假设您将ExtensionAttribute
公开,以便您编写的其他程序集可以使用它。起初这很好,但如果您想使用也有相同想法的第 3 方库怎么办?您添加了对该库的引用,现在您遇到了名称冲突。哎呀。
我还注意到,一些新库仅适用于 .NET 4.0 或 3.5,尽管它们对它的依赖很小,可以使用兼容包或 LinqBridge 解决。
如果有旧 .NET 版本的“兼容包”在一个小 DLL 中定义这些小功能,您可以证明将其包含在任何规模的项目中,那肯定会很好。有这种事吗?
更新:从沉默来看,我想没有这样的事情。如果有兴趣,我可能会自己制作这样一个 OSS 库。所以我的新问题是,如果您正在为 .NET 2、.NET 3.5、.NETCF 或 Silverlight 编写代码,您会错过 .NET 4(与 WCF/WPF 之类的怪物相比)的哪些更小 功能?我将开始列表...
ExtensionAttribute
(不在 .NET 2 中)
Func<...>
和 Action<...>
代表(不在 .NET 2 中)
LINQ-to-objects(不在 .NET 2 中)
Tuple<...>
(不在 .NET 3.5 中)
Lazy<T>
和 Lazy<T,TMetadata>
(不在 .NET 3.5 中)
表达式树(不在 .NET 2 中;在 .NET 3.5 中不完整)
泛型变量(存在于 .NET 2 中,但无法从 C# 3 和 VB 9 访问)
Reflection.Emit
(.NETCF 中缺少;不是一个真正的小功能,但我非常想念它)
【问题讨论】:
相关帖子 - Can I use the task parallel library in a .Net 3.5 project? 【参考方案1】:Theraot 的图书馆
借助条件编译,您可以使用 Theraot's Libraries 中的 Theraot.Core
将大部分 .NET 代码反向移植到从 .NET 2.0 开始的旧版本。
在提到的功能中,包括以下功能:
ExtensionAttribute
Func<...>
和 Action<...>
代表
LINQ 到对象
Tuple<...>
Lazy<T>
和 Lazy<T,TMetadata>
表情发束
还包括问题中未提及的以下功能:
HashSet<T>
SortedSet<T>
ThreadLocal<T>
IObservable<T>
和 IObserver<T>
BigInteger
ConcurrentDictionary<Tkey, TValue>
等等……
注意:计划支持System.Threading.Tasks
。
遗憾的是,在撰写本文时可用的文档很少,但与 BCL 的任何行为差异都可能被视为错误,并且可以是 reported via github。
【讨论】:
我能够使用 Theraot 的库为 .Net 2.0 编译 dotNetLiquid,并且他们的所有单元测试都成功通过(好吧,除了一个 - 但即使我为 .net 4 构建,那个测试也会失败)。使用 LinqBridge 是不够的,因为它不支持表达式。【参考方案2】:对于 .NET 3.5,您可以使用 F# Runtime for .NET Framework 2.0 中的 FSharp.Core.dll。
“此可再发行包中包含的核心库 (FSharp.Core.dll) 在系统命名空间中包含一些 API,这些 API 与 F# 开发所需的 .NET Framework 4 API 相同。”
http://msdn.microsoft.com/en-us/library/ee829875%28v=vs.100%29.aspx
这包括System.Tuple
等。和System.Lazy<T>
。 (虽然不是 Lazy<T,TMetadata>
。)要使用它们,只需参考 FSharp.Core.dll。
编辑:事实证明 FSharp.Core.dll
中的 Lazy 不是直接替代品,而是更多的互操作类。它具有相同的属性,但构造函数不同。相反,它是创建的,例如像这样:
Lazy<string> lazy = Microsoft.FSharp.Control.LazyExtensions.CreateFromValue("test");
【讨论】:
【参考方案3】:这并不是真正的“兼容性包”,但既然你提到了LinqBridge...我经常使用的另一个“反向移植功能”是在框架 3.5 的Reactive Extensions (Rx) 中找到的并行扩展(除其他外) SP1(在System.Threading.dll
)。它包括任务并行库和并行 LINQ (PLINQ) 的完整实现。
对于 .Net 4.0,有来自 Microsoft 的 Async Targeting Pack for Visual Studio 2012 (nuget)。如果使用 C# 5 编译器,它提供了许多异步扩展方法并提供对 async
/await
关键字的支持。
对于 .Net 3.5 也有类似的 AsyncBridge,它基于 Reactive Extentions 的 TPL 库提供 async
/await
。还有一个适用于 .Net 4.0 的 AsyncBridge 版本,但我不知道为什么你会想要那个版本而不是 Microsoft 的版本。
【讨论】:
【参考方案4】:我不知道这样的列表会有多大用处,因为它的规模可能很大。 2.0、3.0 和 3.5 的 CLR 相同,因此从技术上讲,这些 2.0 后的任何功能都可以进入“兼容包”。
-奥辛
【讨论】:
以上是关于用于向后移植新的 .NET Framework 功能的“兼容包”?的主要内容,如果未能解决你的问题,请参考以下文章
如何在新的 .NET Framework 4.6 中启用 SIMD?
在 OSX 10.5 中向后移植 NSWindowDelegates windowDidEndLiveResize 行为?