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
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Net20.LinqBridge" Version="1.6.0.26243" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Net20.LinqBridge" Version="1.6.0.26243" />
                    
Directory.Packages.props
<PackageReference Include="Net20.LinqBridge" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Net20.LinqBridge --version 1.6.0.26243
                    
#r "nuget: Net20.LinqBridge, 1.6.0.26243"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Net20.LinqBridge@1.6.0.26243
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Net20.LinqBridge&version=1.6.0.26243
                    
Install as a Cake Addin
#tool nuget:?package=Net20.LinqBridge&version=1.6.0.26243
                    
Install as a Cake Tool

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 through DynamicMethod, so a compiled lambda runs at the speed of a normal delegate.
  • IQueryable works. EnumerableRewriter rewrites a Queryable expression tree into the equivalent Enumerable calls, so AsQueryable() and any provider written against IQueryProvider execute 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

  1. 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 IQueryProvider this package supplies.
  2. Compile() needs System.Reflection.Emit. The expression compiler emits a DynamicMethod, so it will not work on a platform without run-time code generation. Building and inspecting trees is unaffected.
  3. The expression node set is the 3.5 one, plus the few 4.0 nodes Net20.DynamicBridge needs — Assign, Block and Index. The other 4.0 statement nodes (Loop, Switch, TryCatch, Goto) are not implemented.
  4. System.ComponentModel.DataAnnotations is a deliberate subset — the three types above, not the whole 3.5 assembly.
  5. 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# dynamic keyword on net20/net30/net35, built on this package.
  • Net4x.AsyncBridgeasync/await on frameworks without it.

Licence

New BSD. Copyright (c) 2007, Atif Aziz, Joseph Albahari. All rights reserved.

Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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