静态上下文和派生类型中的 C# 扩展方法

发布于 2024-10-10 03:13:04 字数 2171 浏览 0 评论 0原文

C# 中的现有类型需要使用一些新方法进行扩展,以便满足以下条件:

  1. 扩展方法应该在另一个程序集中抵制
  2. 它们应该像原始类型的 static 方法一样出现,
  3. 它们也应该对它们可见原始类型的派生类的实现者

示例,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() { } 

用法示例(理想):

public class Usage : Orig {
   Method1();  // naturally working
   Method2();  // <- this is needed
}
public void SomeFunc() {
   Orig.Method2();  // <- this should ideally work also 
}    

自然想到的第一个尝试是使用 C# 3.0 的扩展方法。但与我想要的不同,这些(我认为)仅适用于正在扩展的类型的实例。在派生类的上下文中,可以这样归档:

public class Usage : Orig {
   Method1();  // naturally working
   this.Method2();  // working with C# 3.0 extension methods, but clumsy syntax
}

第一个要求(来自程序集外部的静态上下文)似乎根本无法满足?那么还有另一种潜在的方法吗?

@编辑:我可能没有清楚地描述问题。这些需求在以下代码片段中被注释掉(因为它们不适用于常见的 C# 扩展方法)。所以我尝试找到另一种方法,启用注释掉的语法:

    // 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"); 
    }
}

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"); 
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

木緿 2024-10-17 03:13:04
  1. 扩展方法可以存在于与包含要扩展的类型的程序集不同的程序集中。扩展程序集只需要引用原始程序集即可。其他程序集中的任何客户端只需引用原始程序集和扩展程序集。

  2. 扩展方法不能在被扩展的类型上显示为静态方法。它们只能作为实例方法出现。社区中已经有一些关于静态扩展方法的必要性和可能的​​实现的讨论,但据我所知,MS 尚未承诺将此功能添加到 C# 中。

  3. 扩展方法(具有适当的可见性)对于两种派生类型以及这些派生类型的任何使用者都是可见的。

  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.

夜巴黎 2024-10-17 03:13:04

扩展方法或部分类不会帮助您。尝试使用单例设计模式,因为这可能会为您提供使用实例而不是静态成员所需的行为

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文