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 { static void ExtMeth(this Class c) {/*...*/} } Class c = new Class(); c.ExtMeth(); // Equivalent to GenStatic. 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(this Class c) {/*...*/} } Class c = newClass(); c.ExtMeth(); // Equivalent to NonGenStatic.
ExtMeth(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(this SimpleLinkedList where T:IComparable simpleLinkedList) { // code } }.
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 { static void ExtMeth(this Class c) {/*...*/} } Class c = new Class(); c.ExtMeth(); // Equivalent to GenStatic. 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(this Class c) {/*...*/} } Class c = newClass(); c.ExtMeth(); // Equivalent to NonGenStatic.
ExtMeth(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(this SimpleLinkedList where T:IComparable simpleLinkedList) { // code } }.
Good point about the fact that non-generic extension methods on generic static classes would cause headaches. – Johannes Rudolph Apr 12 '10 at 14:40 If the extension method didn't use any static members of the class in which it's contained, it wouldn't matter which class was chosen. You could augment your example by having the extension method use something like a static class field; the choice of field would clearly be semantically relevant, but there would be no way for the compiler to select it.
– supercat Nov 18 at 16:22.
SimpleLinkedList data = new SimpleLinkedList(); 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.
As far as my testing showed the compiler can resolve this! It has nothing to do with the static class being generic. – Johannes Rudolph Apr 12 '10 at 12:37 @Johannes Rudolph: And which method would it choose?
It is not obvious to me at all. – Gorpik Apr 12 '10 at 12:50 @Johannes Rudolph - What test did you do? The original question was about how the second class in the example doesn't compile, so how did you compile this?
– Cameron MacFarland Apr 12 '10 at 13:46 Good point but probably compiler should see this and say something like "Member with the same signature already declared". – Hun1Ahpu Apr 12 '10 at 14:10 @Gorpik, such conflicts also appear when having the same method in two classes. It is a mistery for me too why they forbade this, as is why the class must be static.
But they chose to do so, and you have to live with it... Edit: Actually there is a reason to exlude generic extension methods, but an error about missing parameters would also suit, but be a bit messy. – Dykam Apr 12 '10 at 14:17.
Don't think of extension methods as being tied to the static class in which they are contained. Instead, think of them as being tied to a specific namespace. Therefore, the static class in which they are defined is simply a shell used to declare these methods within the namespace.
And while you could very well write multiple classes for different types of extension methods, you shouldn't think of the class itself as anything more than a way to clearly group your extension methods. Extension methods do not extend any attributes of the class in which they are contained. The signature of the method will define everything about the extension method.
And while you could also call your method like this, LinkedListExtensions. ToArray(...), I do not believe that was the intent for extension methods. As such, I believe the framework creators probably created the restriction you ran into as a way to inform developers simply that extension methods are self-contained and are not directly tied to the class in which they reside.
I am sure you have your reasons but just throwing that out there.
A very interesting question, I have never been tempted to use static generic classes, but at least it seems possible. In the context of declaring extension methods, you cannot only declare extension methods for a certain generic type (such as IEnumerable) but also bring the type parameter T into the equation. If we agree to treat IEnumerable and IEnumerable as different types, this makes sense on a conceptual level too.
Being able to declare your extension methods in a static generic class would save you repeating your type parameter constraints over and over again, in effect grouping all extension methods for IEnumerable where T : IComparable together. According to the specification (citation needed), extension methods can only be declared in static not-nested and not-generic classes. The reason for the first two constraints are fairly obvious: May not carry any state as it's not a mixin, just syntactic sugar.
Must have the same lexical scope as the type it provides extensions for. The restriction on non-generic static classes seems a little arbitrary to me, I can't come up with a technical reason here. But it might be that the language designers decided to discourage you in writing extension methods that depend on the type parameter of a generic class you wish to provide extension methods for.
Instead they want you to provide a truly generic implementation of your extension method but make it possible to provide optimized/specialized (compile-time bound) versions of your extension methods in addition to your general implementation. Reminds me of template specialization in C++. EDIT: Unfortunately this is wrong, please see my additions below.
Ok, as this is a really interesting topic I did some further research. There actually is a technical restriction that I missed here. Let's look at some code: public static class Test { public static void DoSomething(this IEnumerable source) { Console.
WriteLine("general"); } public static void DoSomething(this IEnumerable source) where T :IMyInterface { Console. WriteLine("specific"); } } This will actually fail with this compiler error: Type 'ConsoleApplication1. Test' already defines a member called 'DoSomething' with the same parameter types Ok, next we try splitting it up into two different extensions classes: public interface IMyInterface { } public class SomeType : IMyInterface {} public static class TestSpecific { public static void DoSomething(this IEnumerable source) where T : IMyInterface { Console.
WriteLine("specific"); } } public static class TestGeneral { public static void DoSomething(this IEnumerable source) { Console. WriteLine("general"); } } class Program { static void Main(string args) { var general = new List(); var specific = new List(); general.DoSomething(); specific.DoSomething(); Console.ReadLine(); } } Against my initial impression (it was late yesterday night), this will result in an ambiguity at the call sites. To resolve this ambiguity one would need to call the extension method in a traditional way, but that's against our intention.So this leaves us with a situation where it's not possible to declare compile-time bound generic specializations of extension methods.
On the other hand, there is still no reason why we couldn't declare extension methods only for a single special generic type parameter. Therefore it'd be nice to declare them in a static generic class. On the other hand writing an extension method like: public static void DoSomething(this IEnumerable source) where T : IMyInterface {} or public static void DoSomething(this IEnumerable source) {} is not all too different and only requires a little casting on the call site vs. on the extension method side (you will probably implement some optimization that depends on the specific type, so you'd need to cast T to IMyInterface or whatever anyway).
So the only reason I can come up with is again, the language designers want to encourage you in writing generic extensions only in a truly generic fashion. Some interesting things could happen here if we take co/contravariance in to the equation, which are about to be introduced with C# 4.0.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.