c# - 防止访问继承的成员

标签 c#

这个问题可能有点奇怪。场景如下:

  • 有一个名为 IPlugin 的插件接口(interface)
  • 有一个名为PluginBase的插件抽象基类(它实现了接口(interface))
  • 这些存储在类库中

现在每个人都应该能够通过创建一个新的类库和一个派生自 PluginBase 的插件类来创建自己的插件。

PluginBase 类将提供许多公共(public)属性,这些属性从基础工具中用于与插件接口(interface)进行通信。这是通过反射完成的;该工具搜索基于接口(interface) IPlugin 的类并创建该类的实例。

现在的问题是,这些公共(public)属性是插件机制所必需的,但不应从派生插件类访问或更改。简而言之:用户定义的插件类不应该能够访问其基类 PluginBase 的多个公共(public)成员。

这有可能吗?我知道我通常应该为这些属性使用 private(因此派生类无法访问它们)但是由于基类也充当插件接口(interface),所以这是不可能的。

解决方案(基于 Fabjan 和 Luaan 的回答):

// basic plugin interface (IPlugin.dll)
public interface IPlugin
{
    // plugin communication interface
    string SomeProperty { get; set; }
    void SomeMethod();

    // public interface
    string Name { get; }
    void Run();
}

// plugin base class (IPlugin.dll)
public class PluginBase : IPlugin
{
    string IPlugin.SomeProperty
    {
        get { return "Something"; }
        set { /* ... */ }
    }

    void IPlugin.SomeMethod()
    {
        Console.WriteLine("Something");
    }

    public string Name
    {
        get { return "MyName"; }
    }

    public void Run()
    {
        // ...
    }
}

// user-defined plugin (MyPlugin.dll)
public class MyPlugin : PluginBase
{
    public MyPlugin()
    {
        // will not work
        this.SomeProperty ...
    }
}

// main assembly
static void Main(string[] args)
{
    Assembly asm = Assembly.LoadFrom(@"path\to\assembly");

    var type = asm.GetTypes().FirstOrDefault(t => t.GetInterface("NamespaceOfIPlugin.IPlugin", true) != null);

    NamespaceOfIPlugin.IPlugin plugin = (NamespaceOfIPlugin.IPlugin)Activator.CreateInstance(type);

    // works as expected
    plugin.SomeMethod();
}

最佳答案

如果您不想公开这些属性,请不要公开它们。

您的解决方案的架构充其量似乎是不稳定的。您期望(甚至要求)所有插件都实现PluginBase,但您却根据IPlugin 接口(interface)搜索插件。为什么?选择一个,然后滚动。框架中没有规定必须根据某个接口(interface)来搜索插件。

要防止派生类访问其父类的成员,您可以使用 private 访问修饰符。如果您的插件管理器需要访问这些值,您必须确保它确实如此 - 例如,您可以使负责处理此数据的部分成为 sealed PluginBase 的嵌套类

但最后,问题是 - 为什么?试图强制派生类避免访问这些成员毫无意义(为什么首先要有这些成员?)。也许将这些属性放在一个显式实现的接口(interface)中就足够了?这样你仍然可以使用例如((IPluginBase)plugin).SomeProperty,但不是 plugin.SomeProperty。反正他们也不是不能使用反射获取数据。

关于c# - 防止访问继承的成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31380841/

相关文章:

c# - 未从 Godaddy Hosted Exchange 收到 Exchange 2007 推送通知

c# - C# 中的通用消息传递模式

C# ASPX 错误 - "' Sys 未定义”- 由 "GET https://domain/ScriptResource.axd? 404 (Not Found)"引起

c# - 反编译源中不寻常的 C# 运算符...?

c# - 线程中的 UI 容器?

c# - HttpListenerRequest 未返回客户端证书

c# - PasswordVault Windows Phone 等效?

c# - .Net framework 到底有多跨平台?

c# - 当 regex101 匹配时,RegEx C# 不匹配

c# - 保护我的 ASP .NET 代码以供演示?