Net20.LinqBridge
1.6.0.26243
dotnet add package Net20.LinqBridge --version 1.6.0.26243
NuGet\Install-Package Net20.LinqBridge -Version 1.6.0.26243
<PackageReference Include="Net20.LinqBridge" Version="1.6.0.26243" />
<PackageVersion Include="Net20.LinqBridge" Version="1.6.0.26243" />
<PackageReference Include="Net20.LinqBridge" />
paket add Net20.LinqBridge --version 1.6.0.26243
#r "nuget: Net20.LinqBridge, 1.6.0.26243"
#:package Net20.LinqBridge@1.6.0.26243
#addin nuget:?package=Net20.LinqBridge&version=1.6.0.26243
#tool nuget:?package=Net20.LinqBridge&version=1.6.0.26243
Net20.LinqBridge
LINQ, expression trees and IQueryable on .NET Framework 2.0 and 3.0.
C# 3.0 and Framework 3.5 run on the same CLR 2.0 as Framework 2.0: the compiler emits ordinary IL and
then looks for methods with the right names and signatures — it does not care which assembly they come
from. Framework 3.5 supplies them in System.Core; this package supplies the same types, in the same
namespaces, for targets that have no System.Core at all. Extension methods, lambdas, query
comprehensions, var, object and collection initialisers and anonymous types therefore all compile and
run on a 2.0 target.
int[] numbers = { 5, 15, 7, 12 };
var query = from n in numbers // query comprehension, on a net20 assembly
where n > 10
orderby n
select n * 10;
// expression trees, and compiling one back to a delegate
Expression<Func<int, int>> f = x => x * 2 + 1;
int seven = f.Compile()(3);
// IQueryable, executed in memory
var q = numbers.AsQueryable().Where(n => n > 10).Select(n => n * 10);
Installing
dotnet add package Net20.LinqBridge
<LangVersion>latest</LangVersion> is required in the consuming project: the target framework may be
2.0, but the compiler has to be one that knows the C# 3.0 language features.
| Target | What you get |
|---|---|
| net20, net30 | Full implementation, in the real BCL namespaces. |
| net35 and later, netstandard2.0 | An empty facade. The Framework's own System.Core provides these types, so referencing this package on a modern target changes nothing and cannot cause a CS0433 ambiguity. |
That split is the point: a project that multi-targets net20;net48 gets the bridge where the framework
lacks LINQ and the real thing everywhere else, with no #if in your code. And because everything lives
under the real namespaces, moving a project to 3.5 later is a matter of changing the target framework
and dropping the package reference — no code edits.
The assembly is strong-named. Func<> and Action<> come from the Net35.Actions package, which this
package depends on.
What's in the box
| Namespace | Types |
|---|---|
System.Linq |
Enumerable — the complete set of Framework 3.5 standard query operators, including every numeric overload of Sum/Min/Max/Average; Queryable, IQueryable, IQueryable<T>, IQueryProvider, IOrderedQueryable; IGrouping<K,T>, ILookup<K,T>, Lookup<K,T>, IOrderedEnumerable<T> |
System.Linq.Expressions |
The expression tree node types (Expression, Expression<TDelegate>, LambdaExpression, BinaryExpression, MethodCallExpression, …), ExpressionType, ExpressionVisitor, and an IL-emitting compiler behind LambdaExpression.Compile() |
System.Runtime.CompilerServices |
ExtensionAttribute — what makes extension methods compile on 2.0 — plus StrongBox<T>, IStrongBox, ExecutionScope and ReadOnlyCollectionBuilder<T> |
System.Collections.Generic |
HashSet<T> |
System.ComponentModel.DataAnnotations |
ValidationAttribute, RequiredAttribute, ValidationException |
System.Threading |
Net20Interlocked.CompareExchange<T> |
Two things go beyond the classic LINQBridge, which was LINQ to Objects only:
- Expression trees actually work.
Expression<TDelegate>.Compile()emits IL throughDynamicMethod, so a compiled lambda runs at the speed of a normal delegate. IQueryableworks.EnumerableRewriterrewrites aQueryableexpression tree into the equivalentEnumerablecalls, soAsQueryable()and any provider written againstIQueryProviderexecute in memory.
Behaviour is checked by a differential test suite: the same fixtures are compiled once against this
package (net30) and once against the real System.Core (net35), and must pass identically on both.
Limitations
- LINQ to Objects only. There is no LINQ to SQL, LINQ to XML, LINQ to Entities or PLINQ here; a
remote provider is yours to write against the
IQueryProviderthis package supplies. Compile()needsSystem.Reflection.Emit. The expression compiler emits aDynamicMethod, so it will not work on a platform without run-time code generation. Building and inspecting trees is unaffected.- The expression node set is the 3.5 one, plus the few 4.0 nodes
Net20.DynamicBridgeneeds —Assign,BlockandIndex. The other 4.0 statement nodes (Loop,Switch,TryCatch,Goto) are not implemented. System.ComponentModel.DataAnnotationsis a deliberate subset — the three types above, not the whole 3.5 assembly.ExpressionType's numeric values are a contract. The C# compiler passes node kinds to a runtime binder as bare numeric constants, so members are appended, never inserted. If you fork this, do the same.
See also
Net20.DynamicBridge— the C#dynamickeyword on net20/net30/net35, built on this package.Net4x.AsyncBridge—async/awaiton frameworks without it.
Licence
New BSD. Copyright (c) 2007, Atif Aziz, Joseph Albahari. All rights reserved.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net20 is compatible. net30 is compatible. net35 is compatible. net40 is compatible. net403 was computed. net45 is compatible. net451 was computed. net452 was computed. net46 was computed. net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 2.0
- Net35.Actions (>= 1.4.0.3)
-
.NETFramework 3.0
- Net35.Actions (>= 1.4.0.3)
-
.NETFramework 3.5
- Net35.Actions (>= 1.4.0.3)
-
.NETFramework 4.0
- Net35.Actions (>= 1.4.0.3)
-
.NETFramework 4.5
- Net35.Actions (>= 1.4.0.3)
-
.NETStandard 2.0
- Net35.Actions (>= 1.4.0.3)
NuGet packages (13)
Showing the top 5 NuGet packages that depend on Net20.LinqBridge:
| Package | Downloads |
|---|---|
|
Net4x.Text.RegularExpressions
Provides the System.Text.RegularExpressions.Regex class, an implementation of a regular expression engine. |
|
|
Net4x.BaseTypes
Package Description |
|
|
Net4x.Collections.Immutable
This package provides collections that are thread safe and guaranteed to never change their contents, also known as immutable collections. Like strings, any methods that perform modifications will not change the existing instance but instead return a new instance. For efficiency reasons, the implementation uses a sharing mechanism to ensure that newly created instances share as much data as possible with the previous instance while ensuring that operations have a predictable time complexity. |
|
|
Net4x.Extensions.Logging.Abstractions
Logging abstractions for Ms.Extensions.Logging. |
|
|
Net4x.Extensions.DependencyInjection.Abstractions
Abstractions for dependency injection. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.6.0.26243 | 48 | 8/31/2026 |
| 1.6.0.26241 | 44 | 8/30/2026 |
| 1.6.0.4 | 795 | 7/17/2026 |
| 1.6.0.3 | 192 | 2/15/2026 |