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:
- Create a new console project
- Change it to target .net 2.0
- 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.