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

静态上下文和派生类型中的C#扩展方法,c#,methods,C#,Methods,C#中的现有类型需要使用一些新方法进行扩展,以便满足以下要求: 扩展方法应在另一个程序集中抵抗 它们应该显示为原始类型的静态方法 它们还应该对原始类型的派生类的实现者可见 例如,程序集Orig.dll: public class Orig { public static void Method1() { } } 程序集扩展.dll: // method, which extends Orig in a static context is needed ... // ?? // p

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

  • 扩展方法应在另一个程序集中抵抗
  • 它们应该显示为原始类型的静态方法
  • 它们还应该对原始类型的派生类的实现者可见
  • 例如,程序集Orig.dll:

    public class Orig {
        public static void Method1() { }
    }
    
    程序集扩展.dll:

    // method, which extends Orig in a static context is needed ...  
    // ?? 
    // public static void Method2() { } 
    
    用法示例(理想):

    第一个需求(来自程序集外部的静态上下文)似乎根本不可填充?那么,还有其他可能的方法吗

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

        // 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"); 
        }
    }
    
    //拥有一个类
    公共类源{}
    //通过某些函数(从另一个程序集)扩展
    公共静态类{
    公共静态void ExtMeth(this Orig Orig,string bla){}
    }
    //派生类应该直接使用!!请看分机
    派生的公共类:Orig{
    公共方法(){
    //外部(“内部源”);
    
  • 扩展方法可以存在于与包含要扩展类型的程序集分离的程序集中。扩展程序集只需引用原始程序集。其他程序集中的任何客户端只需引用原始程序集和扩展程序集

  • 扩展方法不能在被扩展的类型上显示为静态方法。它们只能显示为实例方法。社区中已经讨论了静态扩展方法的需要和可能的实现,但据我所知,MS尚未承诺将此功能添加到C#

  • 扩展方法(具有适当的可见性)对派生类型和这些派生类型的任何使用者都是可见的


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

    ,因此您将重点放在C#3.0扩展方法上。我还认为,我的需求与它们不可归档,尽管我正在寻找替代方法。我怀疑你的3.是真的。对于派生类型中的方法,EM将不可见。始终需要类实例。特别是对于派生类型的静态方法,因此不容易访问它们(“需要this”关键字,这在静态方法中不可用)。“所以您将重点放在C#3.0扩展方法上“-还有什么其他类型的扩展方法?扩展方法是在C#3.0和AFAIK中引入的,它们在C#4.0中没有改变,我也没有听说过对C#5.0中的扩展方法有任何计划的改变。第3点是正确的,因为第2点是正确的。第3点说明扩展方法只在实例上可见。“C#中的现有类型需要使用一些新方法进行扩展…”我在问题中添加了另一个代码示例。为什么您的3不正确?它们对派生类型不可见-它们当然在派生类型上或对于派生类型可见。但是在派生类型的方法中,使用“this”关键字(即显式实例引用)总是需要。基类型也是如此。因此,对于静态方法(没有“this”可用),它们根本不可见。单例有什么帮助?另外:切换到实例而不是静态上下文会延长语法。SomeFunc()在我的第一个使用示例中,在实际方法之前总是需要类型引用和实例引用。
    public class Usage : Orig {
       Method1();  // naturally working
       this.Method2();  // working with C# 3.0 extension methods, but clumsy 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"); 
        }
    }