I'd like to create a lot of extension methods for some generic class, e.g. for
public class SimpleLinkedList<T> where T:IComparable
And I've started creating methods like this:
public static class LinkedListExtensions
{
public static T[] ToArray<T>(this SimpleLinkedList<T> simpleLinkedList) where T:IComparable
{
//// code
}
}
But when I tried to make LinkedListExtensions class generic like this:
public static class LinkedListExtensions<T> where T:IComparable
{
public static T[] ToArray(this SimpleLinkedList<T> simpleLinkedList)
{
////code
}
}
I get "Extension methods can only be declared in non-generic, non-nested static class".
And I'm trying to guess where this restriction came from and have no ideas.
EDIT: Still don't have clear vision of the problem. It seems like this was just not implemented for some reason.
Extension methods are defined as static methods but are called by using instance method syntax. Their first parameter specifies which type the method operates on. The parameter is preceded by the this modifier.
It is compulsion that the Extension method must be in a Static class only so that only one Instance is created. For example, if you place the following in ASP.Net page it will not work. Though error will not come, but you will not see the method available. The above will not work.
An extension method must be a static method. An extension method must be inside a static class -- the class can have any name. The parameter in an extension method should always have the "this" keyword preceding the type on which the method needs to be called.
A static generic class is exactly as useful as any given static class. The difference is that you don't have to use copy-and-paste to create a version of the static class for each type you want it to work on. You make the class generic, and you can "generate" one version for each set of type parameters.
Generally speaking, since you do not specify the class when you use an extension method, the compiler would have no way to know which is the class where the extension method is defined:
static class GenStatic<T>
{
static void ExtMeth(this Class c) {/*...*/}
}
Class c = new Class();
c.ExtMeth(); // Equivalent to GenStatic<T>.ExtMeth(c); what is T?
Since extension methods themselves can be generic, this is no real problem at all:
static class NonGenStatic
{
static void GenExtMeth<T>(this Class c) {/*...*/}
}
Class c = newClass();
c.ExtMeth<Class2>(); // Equivalent to NonGenStatic.ExtMeth<Class2>(c); OK
You can easily rewrite your example so that the static class is not generic, but the generic methods are. In fact, this is how .NET classes such as Enumerable
are written.
public static class LinkedListExtensions
{
public static T[] ToArray<T>(this SimpleLinkedList<T> where T:IComparable simpleLinkedList)
{
// code
}
}
The problem is how does the compiler do the extension resolution?
Say you define both the methods you describe:
public static class LinkedListExtensions {
public static T[] ToArray<T>(this SimpleLinkedList<T> simpleLinkedList) where T:IComparable {
//// code
}
}
public static class LinkedListExtensions<T> where T:IComparable {
public static T[] ToArray(this SimpleLinkedList<T> simpleLinkedList) {
////code
}
}
Which method is used in the following case?
SimpleLinkedList<int> data = new SimpleLinkedList<int>();
int[] dataArray = data.ToArray();
My guess is that the language designers decided to restrict extension methods to the non-generic types to avoid this scenario.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With