Why aren't we allowed to make SomeClass.GetOutput an extension method?
You can but not with the standard C# tools.
To the C# compiler, an extension method for a type is a static method that takes an instance of that type as its first parameter and is marked with System.Runtime.CompilerServices.ExtensionAttribute.
When defining an extension method in C#, the C# compiler won't allow the application of that attribute at all, suggesting that you use the this
syntax, which does have the cited requirements. So, you could define the SomeClass
in some other language or use a tool that adds the attribute after the C# compiler is done.
PostSharp (non-free edition) can do that. Just mark GetOutput
with a different attribute and write code to replace it with System.Runtime.CompilerServices.ExtensionAttribute.
public class SomeClass
{
[ExtensionAspect]
public static IEnumerable<SomeClass> GetOutput(IEnumerable<SomeClass> items)
{
return items;
}
}
GetOutput
is marked with ExtensionAspectAttribute
, which is derived from a PostSharp aspect. Post-processing during the build runs the ProvideAspect
method, which adds the desired attribute.
[AttributeUsage(AttributeTargets.Method)]
public class ExtensionAspectAttribute : MethodLevelAspect, IAspectProvider
{
public IEnumerable<AspectInstance> ProvideAspects(object targetElement)
{
var constructorInfo = typeof (System.Runtime.CompilerServices.ExtensionAttribute).GetConstructor(Type.EmptyTypes);
var objectConstruction = new ObjectConstruction(constructorInfo);
var aspectInstance = new CustomAttributeIntroductionAspect(objectConstruction);
yield return new AspectInstance(targetElement, aspectInstance);
}
}
So, in another project that references the binary assembly for SomeClass, this works:
var items = new [] { new SomeClass() };
var results = items.GetOutput();
That satisfies the C# compiler, however Intellisense doesn't see it as an extension method and ReSharper colors it as an error.
Of course, this is an academic exercise because there is little reason to not define the extension method in SomeClassExtensionMethods
especially since it can be done in the same namespace and even the same .cs file as SomeClass.