This is an unfortunate discoverability issue with extension methods. In order to make them available you need to add a using
statement for the namespace containing the static class that has the extensions. Check out this blog about extension methods.
Here is some background on extension methods:
So how is the compiler to know which
extension method to bind? The compiler
looks for extension methods in the
innermost namespace when the call is
made for extension methods and then in
all the namespaces imported by the
"using" clause. This process is
followed moving outward until we reach
the topmost namespace.
Since extension methods can be
imported in to the current context by
the "using" clause and bound to any
object which is assignable(see
convertibility section for details) to
the instance parameter, all sorts of
interesting possibilities open up for
extending the methods implemented by a
type. This can simply be done by
importing a library of extension
methods and using these methods as if
they were declared on a type that you
don't own. This means that
Depending on the library you import the code can be made to do different
things.
The client gets an interesting way to extend a type that he does not own.
My understanding is that using extension methods is just like using any other type, except that you can't qualify them (that is just syntactically impossible), hence the need for using
statement. Since you can define multiple of them in different classes in different namespaces, the compiler needs a way to resolve ambiguity.
I envisage that in future Visual Studio will add a feature to import the right namespace when you type in the method name, in a similar way it does so for class and interface names.
Consider this scenario:
namespace FruityNamespace {
public static class FruityExtensions {
public static string ToFunString(this int value) {return value + " bananas"; }
}
}
namespace VegetablNamespace {
public static class VegetablyExtensions {
public static string ToFunString(this int value) {return value + " carrots"; }
}
}
//In some other source file
static void Main(/**/) {
int things = 3;
3.ToFunString(); //error CS1061: 'System.Int' does not contain a definition for 'ToFunString' and no extension method 'ToFunString' accepting a first argument of type 'System.Int' could be found (are you missing a using directive or an assembly reference?)
}
In order to use any of those extension methods you need to import the right namespace:
using FruityNamespace;
//OR
using VegetablyNamespace;
You might ask what happens when you import both namespaces. You get a compiler error just like this:
error CS0121: The call is ambiguous between the following methods or properties: 'VegetablNamespace.VegetablyExtensions.ToFunString(int)' and 'FruityNamespace.FruityExtensions.ToFunString(int)'