【问题标题】:Private Members on an Interface接口上的私有成员
【发布时间】:2013-01-03 16:47:23
【问题描述】:

我对整个 C# 有点陌生,但基本上我正在为我正在开发的应用程序编写基于插件的架构。每个插件都需要有一些基本的东西,所以我有一个界面如下:

interface IPlugin
{
   string Username {get;}
   string Password {get;}
}

问题是用户名和密码只会在实现接口的类中使用,因此不需要公开。

这意味着我不能使用接口,因为它只允许公开。我在想我可以使用一个抽象类,但是我需要在一个类成员上放置什么正确的访问修饰符以便我可以实现当我从类继承时我可以看到它。

我尝试了以下方法,但它从来没有奏效,我知道为什么它不起作用,我只是不知道正确的修饰符是什么。

abstract class Plugin
{
  private string Username;
}

class Imp : Plugin
{
  this.Username = "Taylor";
}

【问题讨论】:

  • 你想通过接口强制私有实现吗?

标签: c# .net


【解决方案1】:

您是正确的,接口只公开公共方法和属性。您不能在接口中设置访问修饰符。

鉴于您的情况,创建摘要可能是一种正确的方法。要使字段或属性仅对从抽象类继承的类可见,您应该使用protected 访问修饰符。

欲了解更多信息:protected access modifier

在你的例子中:

abstract class Plugin
{
   protected string Username;
}

class Imp : Plugin
{
  public Imp()
  {
      this.Username = "Taylor"; // No error here...
  }
}

【讨论】:

  • 抱歉,您的代码无法编译。您必须将Username 初始化放入构造函数或方法中。
  • @IlyaIvanov 正确。固定。
【解决方案2】:

正如其他人所说,正确的方法是将抽象类作为基类。这意味着只有您的Imp 班级才能访问Username。但是你可以通过接口实现接近这一点,尽管并不完全如此。

interface IPlugin
{
    string Username { get; }
}

class Imp : IPlugin
{
    string IPlugin.Username
    {
        get { return "Taylor"; }
    }
}

关键是接口的explicit implementation。现在你将无法做到:

new Imp().Username; //error 

但你可以做到:

((IPlugin)new Imp()).Username; //works

在显式实现中,Username 仅对接口实例公开,对派生类型实例不公开。

为什么不允许private,见Non Public Members for C# Interfaces

【讨论】:

    【解决方案3】:

    尝试使用protected修饰符,以便子类可以访问字段

    abstract class Plugin
    {
      protected string Username;
      protected string Password;
    }
    
    class Imp : Plugin
    {
        public Imp()
        {
            base.Username = "Taylor";
            base.Password = "Pass";
        }
    }
    

    您可以省略base 访问器或改用this,但我已经习惯明确说明我要更改的内容。它使代码更具可读性并且不那么模棱两可。

    【讨论】:

    • 是的,您完全可以不使用thisbase 访问,但我想明确说明我正在设置父类的字段。
    • 使用 this 或 base 会有什么不同吗?例如,如果您回溯到抽象类,使用 base 代替 this 关键字是否有益?
    • 不,没有任何区别。唯一的情况是当您在子类中有另一个 Username 字段时,当您添加 base 修饰符时 - 您将访问基类的字段,在其他情况下 - 当前类的字段。 if you cast back up to the abstract class 访问类的引用类型无关紧要。
    【解决方案4】:

    正确的修饰符是protected。在这种情况下,您使用抽象类而不是接口是正确的 - 接口是一种契约,因此外部世界知道实现者的某些功能,而抽象类可能(并且经常)包含该逻辑使用的一些逻辑和受保护的成员.

    【讨论】:

      【解决方案5】:

      我认为您正在寻找 protected 关键字,如下所示:

      abstract class Plugin
      {
          protected string Username;
      }
      

      【讨论】:

        【解决方案6】:

        您正在寻找 protected 修饰符。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-03-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-01-12
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多