Adding Extension Methods to 2.0

Today, I was compiling a solution and attempting to get rid of all compiler warnings. There was one that I couldn’t get rid of.

Warning 1 The predefined type ‘System.Runtime.CompilerServices.ExtensionAttribute’ is defined in multiple assemblies in the global alias; using definition from ‘c:\temp\ConsoleApplication2\Program.cs’ ConsoleApplication2

That one is from the sample code (below). The actual one was produced by Gallio.

Extension methods were introduced in .NET 3.0. .NET 3 and 3.5 use the .NET 2 Runtime; they just add a ton of stuff to do it.

If you have 3.0 installed, but your project targets 2.0, you can still use extension methods by adding this code somewhere in your project:

   1: namespace System.Runtime.CompilerServices

   2: {

   3:     public class ExtensionAttribute : Attribute

   4:     {

   5:     }

   6: }

It creates an attribute that is part of the underlying magic that makes extension methods work. It doesn’t exist in 2.0 until you add it yourself. The compiler will find the attribute (not caring that it came from you), and will implement aforementioned magic. Sneaky.

To see this action:

  1. Create a new console project
  2. Change it to target .net 2.0
  3. Paste the following code
   1: namespace ConsoleApplication2

   2: {

   3:     class Program

   4:     {

   5:         static void Main(string[] args)

   6:         {

   7:         }

   8:     }

   9:  

  10:     public class IceCream

  11:     {

  12:     }

  13:  

  14:     public static class ExtensionMethods

  15:     {

  16:         public static void Melt(this IceCream iceCream)

  17:         {        

  18:         }

  19:     }

  20: }

 

Now Compile.

You will get this error:

Error 1 Cannot define a new extension method because the compiler required type ‘System.Runtime.CompilerServices.ExtensionAttribute’ cannot be found. Are you missing a reference to System.Core.dll? c:\temp\ConsoleApplication2\Program.cs 16 33 ConsoleApplication2

Now, add to the code the ExtensionAttribute shown earlier in this post, and compile again. This time, it compiles. You now have extension methods in a 2.0 project. Why? Because 3.0 added the ability to the 2.0 compiler, and you exposed the ability by providing the essential attribute.

Here comes the itsy bitsy problem. Change the project to 4.0 and compile. It will compile, but you get this warning:

Warning 1 The predefined type ‘System.Runtime.CompilerServices.ExtensionAttribute’ is defined in multiple assemblies in the global alias; using definition from ‘c:\temp\ConsoleApplication2\Program.cs’ ConsoleApplication2

The problem is that you have declared the extension attribute yourself, and it also exists in mscore. So, there are two of the same attributes, and it doesn’t know which to use. I don’t know how it makes the decision on which to use, but in this case it chose mine. Mine must be cooler. I knew there was something special about it when I typed it.

Gallio

Now that we’re through all that: my specific problem earlier is that my project had a reference to GALLIO.DLL. Gallio.dll must define the attribute to make extension methods available for itself in 2.0. So, I can’t get rid of the warning without dropping the Gallio.

Or, perhaps there’s a newer version of Gallio that doesn’t add this attribute automatically. I haven’t looked into it.

Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: