В C# есть ли способ переопределить приватную или публичную функцию через плагин?

У меня есть приложение, которое загружает плагины. У меня есть плагин, который имеет полный доступ к экземпляру формы. Если у меня есть функция в форме, которая должна быть переопределена, но не является виртуальной функцией, есть ли другой способ переопределить ее?

Вот очень общий пример:

//Form I am modifying
public partial class MyForm : Form
{
    public int myVariable1;
    public int myVariable2;

    //Constructor and other methods here

    private void setVar(int replacementValue)
    {
        myVariable1 = replacementValue;
    }
}

... тогда в отдельной DLL...

//My plugin
public class MyPlugin : IMyPluginBase
{
    MyForm theForm; //Reference to the form in the main application

    //Constructor and other methods here

    private void setVar(int replacementValue)
    {
        theForm.myVariable2 = replacementValue;
    }
}

В этом примере функция в форме устанавливает 'myVariable1', а функция 'setVar' в плагине устанавливает 'myVariable2'.

Итак, вопрос в этом примере, могу ли я заменить / переопределить функцию setVar формы на функцию в плагине? Может быть, с сообщениями или размышлениями?

3 ответа

Решение

Нет. Вы не можете "заменить" или переопределить частные не виртуальные методы в C#.

Язык C# (и среда выполнения.NET) не поддерживают динамическую замену методов описанным вами способом. Насколько мне известно, очень немногие языки поддерживают эту возможность (я полагаю, что оба поддерживают SmallTalk и Objective-C).

Если это единственное место в вашем приложении, где вам нужна такая расширяемость, вы можете достичь этого с помощью интерфейса, делегирования или наследования + виртуальных методов. Любой из этих подходов может сработать... какой из них вы выберете, зависит от того, какую расширяемость вы желаете.

Если вы ожидаете, что в вашем приложении будет много таких точек расширения, то вам, вероятно, стоит взглянуть на Managed Extensibility Framework (MEF). Он предоставляет поддерживаемую Microsoft модель для создания подключаемых архитектур с использованием шаблонов и техник, которые хорошо работают в.NET.

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

Краткий ответ на ваш вопрос - нет. Однако вы можете дать своей форме копию IMyPluginBase и вызвать Form.setVar() для MyPluginBase.SetVar().

Код будет выглядеть примерно так:

public partial class MyForm : Form
{
    public int myVariable1;
    public int myVariable2;

    public IMyPluginBase MyPlugin;

    //Constructor and other methods here

    private void setVar(int replacementValue)
    {
        MyPlugin.setVar(replacementValue);
        //myVariable1 = replacementValue;
    }
}

public class MyPlugin : IMyPluginBase
{
    MyForm theForm; //Reference to the form in the main application
    public void setVar(int replacementValue)
    {
        theForm.myVariable2 = replacementValue;
    }
}

Обратите внимание, что setVar () необходимо определить в IMyPluginBase.

Другие вопросы по тегам