2

我有一个加载插件的应用程序。我有一个可以完全访问表单实例的插件。如果我有一个需要覆盖但不是虚函数的形式的函数,是否有另一种方法来覆盖它?

这是一个非常通用的示例:

//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”函数吗?也许有信息或反思?

4

3 回答 3

2

不可以。您不能“替换”或覆盖 C# 中的私有非虚拟方法。

C# 语言(和 .NET 运行时)不支持以您描述的方式动态替换方法。据我所知,很少有语言支持这种功能(我相信 SmallTalk 和 Objective-C 都支持)。

如果这是您的应用程序中唯一需要这种可扩展性的地方,您可以通过接口、委托或继承+虚拟方法来实现它。这些方法中的任何一种都可以工作......您选择哪种方法取决于您想要什么样的可扩展性。

如果您希望在您的应用程序中有许多这样的可扩展点,那么您可能应该看看托管可扩展性框架(MEF)。它提供了一个 Microsoft 支持的模型,用于使用在 .NET 中运行良好的模式和技术来创建插件架构。

于 2010-12-06T21:57:29.677 回答
1

如果一个函数未标记为虚拟函数或您的类实现的接口的一部分,那么您完全有 0 机会覆盖它。没有插件,没有反射,什么都没有,只是忘记它或使用其他一些动态语言而不是 C#。

于 2010-12-06T21:59:08.787 回答
0

您的问题的简短回答是否定的。但是,您可以做的是给您的表单一个 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 中定义。

于 2010-12-06T21:57:13.720 回答