简体   繁体   中英

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:

  1. extension methods should resist in another assembly
  2. they should appear like static methods of the original type
  3. 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 :(

        // Derived.ExtMeth("static derived"); <- does not work
        new Derived().ExtMeth("outside derived"); 
    }
}
  1. 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.

  2. 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.

  3. 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM