В 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.