Методы расширения C # в статических контекстах и ​​производных типах - PullRequest
0 голосов
/ 04 января 2011

Существующий тип в 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"); 
    }
}

Ответы [ 2 ]

2 голосов
/ 04 января 2011
  1. Методы расширения могут существовать в отдельной сборке из сборки, содержащей тип, который вы хотите расширить.Расширяющая сборка просто должна ссылаться на оригинальную сборку.Любые клиенты в других сборках просто должны ссылаться как на исходную сборку, так и на расширяющуюся сборку.

  2. Методы расширения не могут отображаться как статические методы для расширяемого типа.Они могут появляться только как методы экземпляра.В сообществе было некоторое обсуждение необходимости статических методов расширения и возможных реализаций, но, насколько я знаю, MS еще не взяла на себя обязательство добавлять эту функцию в C #.

  3. Методы расширения (с соответствующей видимостью) будут видны как производным типам, так и любому потребителю этих производных типов.

0 голосов
/ 04 января 2011

Методы расширения или частичные классы не помогут вам. Попробуйте использовать шаблон проектирования Singleton, поскольку это может дать вам поведение, которое вам требуется при использовании экземпляра, а не статических элементов

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...