Каков наилучший способ добавить пользовательские функции в существующий код в C #? - PullRequest
2 голосов
/ 21 января 2009

Скажем, например, у меня много веб-приложений, использующих одну и ту же библиотеку классов, скомпилированную в dll в C #, и я хочу обновить определенный метод класса для конкретного приложения. Я не хочу изменять существующий код, потому что он затронет всех, и я не хочу наследовать от класса, чтобы создать новый. Я просто хочу изменить существующий метод класса для отдельного приложения.

Одним из способов достижения этого было бы иметь скомпилированные классы в качестве «базовых» классов и иметь отдельный файл, содержащий все переопределенные классы, наследующие базовые классы. Тогда приложения будут использовать унаследованные классы. Затем, чтобы изменить класс для отдельного приложения, вы можете просто обновить унаследованные классы. Единственная проблема, которую я вижу с этим методом, состоит в том, что каждому приложению потребуются 2 файла, один из базовых классов и один из наследуемых (вероятно, не скомпилированных).

Кто-нибудь может порекомендовать лучший способ сделать это?

Ответы [ 8 ]

5 голосов
/ 21 января 2009

Может быть, методы расширения будут работать?

2 голосов
/ 21 января 2009

Если вы просто хотите добавить материалы в методы, а не изменять их содержимое, вы можете использовать Аспектно-ориентированное программирование (AOP). В C # это можно сделать с помощью PostSharp или AspectDNG .

AOP фокусируется на разделении задач: вы пишете методы, содержащие только бизнес-логику, а все остальные аспекты приложения (безопасность, ведение журналов и т. Д.) Инкапсулируются в свои собственные модули. Во время компиляции код этих аспектов внедряется в бизнес-код в определенных вами местах.

Вы также можете взглянуть на этот вопрос . Несмотря на то, что этот вопрос направлен именно на изменение методов во время выполнения, некоторые ответы могут дать вам некоторые подсказки.

2 голосов
/ 21 января 2009

Вы не можете изменить реализацию скомпилированного метода; полиморфизм является одним из вариантов; другой - инкапсуляция, возможно, через шаблон декоратора через интерфейс, с использованием фабрики для создания экземпляра - т.е.

interface IFoo { void Bar();}
class Foo : IFoo {public void Bar() { /* imp 1 */ } }
class FooWrapper : IFoo {
    IFoo parent;
    public FooWrapper(IFoo parent) {this. parent = parent;}
    public void Bar() { /* imp 2, perhaps using "parent" }
}

(я не буду возражать с примером полиморфизма)

Полиморфизм и декорирование достигают аналогичного результата, но имеют разные плюсы / минусы - например, декораторы могут быть собраны в гибкие цепочки для разных сценариев.

При любом другом подходе (например, методах расширения) вы в конечном итоге вызываете другой метод; если это подходит, тогда хорошо.

0 голосов
/ 21 января 2009

Методы расширения. Это должно быть добавлено к статическому классу. Вам следует посетить: http://weblogs.asp.net/scottgu/archive/2007/03/13/new-orcas-language-feature-extension-methods.aspx

Пример метода расширения для класса DateTime, который возвращает номер недели:

public static int WeekNumber(this DateTime dtPassed)
    {
        CultureInfo ciCurr = CultureInfo.CurrentCulture;
        int weekNum = 0;
        try
        {
            weekNum = ciCurr.Calendar.GetWeekOfYear(dtPassed,
           CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Sunday);
        }
        catch (Exception ex)
        {
            //TODO: Add error handling code
        }

        return weekNum;
    }
0 голосов
/ 21 января 2009

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

BaseClasses.cs

public class BaseUser {

    public BaseUser() {}

    public bool login() {

        return false;

    }

}

Classes.cs

public class User : BaseUser {}

Применение

User u = new User();
u.login(); 
0 голосов
/ 21 января 2009

Можно ли сделать метод в библиотеке классов Virtual? Это позволит вам переопределить его там, где вы хотите, но сохранить его «как есть» в противном случае.

0 голосов
/ 21 января 2009

Кажется странным, что вы не можете переопределить существующий метод без использования унаследованного класса. Это очень просто в таких языках, как JavaScript. Приведенные выше предложения дали мне пищу для размышлений, но мои первоначальные идеи не улучшают. Методы расширения не позволяют изменять существующий метод. С инкапсуляцией мне все равно нужно использовать новый класс.

Скажем, у меня было 10 приложений, использующих класс User с методом login (). Я не хочу менять, где этот метод вызывается (т.е. изменение имени класса или параметров метода). Я просто хочу изменить сам метод для этого приложения, чтобы можно было выполнить дополнительные проверки перед возвратом.

0 голосов
/ 21 января 2009

Я думаю, что методы расширения - лучший вариант. Для получения дополнительной информации перейдите здесь .

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