Using Sse in C# Is It Possible

Can I use extension methods and LINQ in .NET 2.0 or 3.0?

Extension methods were not added to .NET until 3.5. However, it was not a change to the CLR, but a change to the compiler that added them, so you can still use them in your 2.0 and 3.0 projects! The only requirement is you must have a compiler that can create 3.5 projects to be able to do this workaround (Visual Studio 2008 and above).

The error you get when you attempt to use an extension method is misleading as you do not truly need System.Core.dll to use extension methods. When you use a extension method, behind the scenes, the compiler is adding the [Extension] attribute to the function. If you have a compiler that understands what to do with the [Extension] attribute you can use it in your 2.0 and 3.0 projects if you create the attribute yourself.

Just add the following class to your project and you can then start using extension methods:

namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public class ExtensionAttribute : Attribute
{
}
}

The above code block is sitting inside System.Core.Dll, so that is why the error says you need to include the DLL file to use them.


Now if you want LINQ functionality that will take a little extra work. You will need to re-implement the extension methods yourself. To mimic the full LINQ to SQL functionality the code can get quite complicated. However, if you are just using LINQ to Objects most LINQ methods are not complicated to implement. Here are a few LINQ to Objects replacement functions from a project I wrote out to get you started.

public static class LinqReplacement
{
public delegate TResult Func<T, TResult>(T arg);
public delegate TResult Func<T1, T2, TResult>(T1 arg1, T2 arg2);

public static TSource First<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
if (source == null)
throw new ArgumentNullException("source");
if (predicate == null)
throw new ArgumentNullException("predicate");

foreach (TSource item in source)
{
if (predicate(item) == true)
return item;
}

throw new InvalidOperationException("No item satisfied the predicate or the source collection was empty.");
}

public static TSource FirstOrDefault<TSource>(this IEnumerable<TSource> source)
{
if (source == null)
throw new ArgumentNullException("source");

foreach (TSource item in source)
{
return item;
}

return default(TSource);
}

public static IEnumerable<TResult> Cast<TResult>(this IEnumerable source)
{
foreach (object item in source)
{
yield return (TResult)item;
}
}

public static IEnumerable<TResult> SelectMany<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, IEnumerable<TResult>> selector)
{
if (source == null)
throw new ArgumentNullException("source");
if (selector == null)
throw new ArgumentNullException("selector");

foreach (TSource item in source)
{
foreach (TResult subItem in selector(item))
{
yield return subItem;
}
}
}

public static int Count<TSource>(this IEnumerable<TSource> source)
{
var asCollection = source as ICollection;
if(asCollection != null)
{
return asCollection.Count;
}

int count = 0;
foreach (TSource item in source)
{
checked //If we are counting a larger than int.MaxValue enumerable this will cause a OverflowException to happen when the counter wraps around.
{
count++;
}
}
return count;
}
}

A library with the full re-implemenation of LINQ to Objects with the ExtensionAttribute already added in can be found in the LinqBridge project (Thanks Allon Guralnek).

Using Extension Methods with .NET Framework 2.0

There is an ugly hack that gets Extension methods working in .Net 2.0; but it would better just to upgrade your framework to 3.5.

Alternate Sources: 1, 2.

In short (from link #2): Extension methods are just normal static methods tagged with the [Extension] attribute. This attribute is actually just added by the compiler behind the scenes. In .NET 3.5, it lives in System.Core, so just define your own attribute like this:

namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public class ExtensionAttribute : Attribute
{
}
}

Why does Microsoft use extension methods for their own classes?

There are a number of reason Microsoft did this. The two biggest being:

  1. Extension methods apply to interfaces, not just classes. Had Microsoft simply added the Linq methods directly to IEnumerable, it would have required every concrete implementation of that interface to implement those methods as well. By making them extension methods, written in terms of the existing IEnumerable<> behavior, every IEnumerable<> class gets them automatically.

  2. For the 3.0 and 3.5 Frameworks, the core System.dll is the 2.0 library. Everything new in 3.0 ad 3.5 was added on top of that, in System.Core or other related libraries. The only way to get, for example, a new method in the List<> class that exists in 3.5 but not in 2.0 is to make in an extension method available in a 3.5 library.

Using extension methods in .NET 2.0?

Like so:

// you need this once (only), and it must be in this namespace
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class
| AttributeTargets.Method)]
public sealed class ExtensionAttribute : Attribute {}
}
// you can have as many of these as you like, in any namespaces
public static class MyExtensionMethods {
public static int MeasureDisplayStringWidth (
this Graphics graphics, string text )
{
/* ... */
}
}

Alternatively; just add a reference to LINQBridge.

LINQ extension methods not available for EnumerableRowCollectionTRow

Are you missing

using System.Linq;

by any chance? Once you've got an EnumerableRowCollection<TRow> it should be fine. (The main problem using a DataTable if if you forget to call AsEnumerable, but that isn't a problem here.)

How to use Extension method inside a LINQ statement?

Becasue EF can't translate that extension method to SQL. Simplest way to fix it is to shift to Linq-to-Objects using AsEnumerable() (which is effectively what foreach does):

var model = entity.AsEnumerable()
.Select(e => new SummaryViewModel
{
Address = e.Address.ToOneLine(), Id = e.Id
}).ToList();

Unlike ToList, using AsEnumerable does not create an additional collection in memory, it just binds the Linq calls to Enumerable instead of Queryable, so the mapping is done in memory instead of in SQL.

Escape Catch-22 with extension attributes in .NET 2.0

We ran into the same issue with IronPython. http://devhawk.net/2008/10/21/the-fifth-assembly/

We ended up moving our custom version of ExtensionAttribute to its own assembly. That way, customers could choose between referencing our custom ExtensionAttribute assembly or System.Core - but never both!

The other tricky thing is that you have to always deploy the ExtensionAttribute assembly - even if you don't reference it in your project. Your project assemblies that expose extension methods will have an assemblyref to that custom ExtensionAttribute assembly, so CLR will get upset if it can't be found.

Given the hard requirement of .NET 2.0 support, I would think the best bet would be to simply not use extension methods at all. I'm not familiar with the ImageResizer project, but it sounds like this was a recent change in ImageResizer. How feasible would it be to change the extension methods to traditional static methods? We actually thought about that for IronPython/DLR, but it wasn't feasible (We were merged with LINQ at that point and LINQ had made heavy use of extension methods for essentially its entire existence).

What features of .NET 3.5 can be used in a .NET 2.0 application?

With no external libraries you can use

  • Lambda expressions
  • Object Initializers
  • Collection Initializers
  • Extension Methods
  • Autoproperties

With the help of an external library like LINQBridge you can also use in memory LINQ queries.

The main feature you cannot use are expression trees because they rely on fixes in the CLR which are not present in a vanilla 2.0 install

What's the C#-idiomatic way for applying an operator across two lists?

var c = a.Zip(b, (x, y) => x * y);

For the more complex one after your edit:

var c = a.Zip(b, (x, y) => x > y ? x - y : 0);

Note that Zip is an extension method both from Enumerable that acts on IEnumerable<T> and from Queryable that acts on IQueryable<T>, so it is possible that, should the lambda be one a given query provider can deal with, that it could be processed as a SQL query on a database, or some other way other than in-memory in .NET.

Someone mentioned that this was new with 4.0 in the comments. It's not hard to implement for 3.5 yourself:

public class MyExtraLinqyStuff
{
public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult>(this IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TSecond, TResult> resultSelector)
{
//Do null checks immediately;
if(first == null)
throw new ArgumentNullException("first");
if(second == null)
throw new ArgumentNullException("second");
if(resultSelector == null)
throw new ArgumentNullException("resultSelector");
return DoZip(first, second, resultSelector);
}
private static IEnumerable<TResult> DoZip<TFirst, TSecond, TResult>(this IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TSecond, TResult> resultSelector)
{
using(var enF = first.GetEnumerator())
using(var enS = second.GetEnumerator())
while(enF.MoveNext() && enS.MoveNext())
yield return resultSelector(enF.Current, enS.Current);
}
}

For .NET2.0 or .NET3.0 you can have the same, but not as an extension method, which answers another question from the comments; there wasn't really an idiomatic way of doing such things in .NET at that time, or at least not with a firm consensus among those of us coding in .NET then. Some of us had methods like the above in our toolkits (though not extension methods obviously), but that was more that we were influenced by other languages and libraries than anything else (e.g. I was doing things like the above because of stuff I knew from C++'s STL, but that was hardly the only possible source of inspiration)

LINQ on the .NET 2.0 Runtime

There are some "Hacks" that involve using a System.Core.dll from the 3.5 Framework to make it run with .net 2.0, but personally I would not want use such a somewhat shaky foundation.

See here: LINQ support on .NET 2.0

  1. Create a new console application
  2. Keep only System and System.Core as referenced assemblies
  3. Set Copy Local to true for System.Core, because it does not exist in .NET 2.0
  4. Use a LINQ query in the Main method. For example the one below.
  5. Build
  6. Copy all the bin output to a machine where only .NET 2.0 is installed
  7. Run

(Requires .net 2.0 SP1 and I have no idea if bundling the System.Core.dll violates the EULA)



Related Topics



Leave a reply



Submit