C# Extension methods in static contexts and derived types
An existing type in C# need to be extended with some new methods, so that the following meets:
- extension methods should resist in another assembly
- they should appear like static methods of the original type
- they should also be visible to implementors of derived classes of the original type
Example, Assembly Orig.dll:
public class Orig {
public static void Method1() { }
}
Assembly Extend.dll:
// method, which extends Orig in a static context is needed ...
// ??
// public static void Method2() { }
Usage Example (ideal):
public class Usage : Orig {
Method1(); // naturally working
Method2(); // <- this is needed
}
public void SomeFunc() {
Orig.Method2(); // <- this should ideally work also
}
The first attempt naturally coming in mind is using extension methods of C# 3.0. But unlike what I want, these (I think) only work on instances of the type being extended. In the context of a derived class this could be archieved like so:
public class Usage : Orig {
Method1(); // naturally working
this.Method2(); // working with C# 3.0 extension methods, but clumsy syntax
}
The first requirement (static context from outside the assembly) seems not to be fullfillable at all? So is there another potential approach?
@Edit: I may have not described the problem clearly. The needs are commented out in the following snippet (because they do not work with the common C# extension methods). So I try to find another approach, enabling the out-commented syntax:
// having a class
public class Orig { }
// which is extended with some functions (from another assembly)
public static class ExtOrig {
public static void ExtMeth (this Orig orig, string bla) {}
}
// derived classes should DIRECTLY!! see the extension
public class Derived : Orig {
public void MyMethod() {
// ExtMeth("inside orig"); <- does not work
this.ExtMeth("this derived"); // <- this keyword needed
}
// for static methods even worse:
public static void MyMethod2() {
// ExtMeth("inside orig"); <- does not work
// this.ExtMeth("this derived"); // <- 'this' not usable here :(
}
}
// for shorter syntax, static access would be needed
public class SomeClass {
private void SomeFunc() {
// Orig.ExtMeth("static orig"); <- does not work
new Orig().ExtMeth("outside orig"); // <- instance needed :(
开发者_Go百科 // Derived.ExtMeth("static derived"); <- does not work
new Derived().ExtMeth("outside derived");
}
}
Extension methods can exist in a seperate assembly from the assembly containing the type you want to extend. The extending assembly simply needs to reference the original assembly. Any clients in other assemblies simply have to reference both the original assembly and the extending assembly.
Extension methods cannot appear as static methods on the type being extended. They can only appear as instance methods. There has been some discussion in the community about the need for static extension methods and possible implementations but, as far as I know, MS have not committed to adding this feature to C# as of yet.
Extension methods (with appropriate visibility) will be visible to both derived types, and any consumer of those derived types.
Extension methods or partial classes wont help you. Try using the Singleton design pattern as this may give you the behaviour you require using instance rather than static members
精彩评论