【问题标题】:Using an internal type used as protected field使用用作受保护字段的内部类型
【发布时间】:2012-09-19 20:27:47
【问题描述】:

我有一个类库,其中包含 2 个从抽象类继承的公共类。在抽象类上,我有一个受保护的字段,只能被继承的类访问。该字段使用的类型是内部类的类型。

例如我有:

internal class MyInternalClass
{
    ...
}

public abstract class MyAbstractClass
{
    protected MyInternalClass myField;
}

现在我知道这是行不通的,因为如果从 MyAbstract 类派生的类之一在程序集之外扩展,则访问 myField 将是非法的。

我的问题是如何在保持 MyInternalClass 内部(不应在程序集外部访问它)并允许程序集中的类扩展 MyAbstractClass 以访问 myField 的同时使事情正常工作?

【问题讨论】:

标签: c# .net


【解决方案1】:

创建MyAbstractClass 需要和MyInternalClass 实现的公共接口。

这样的东西,所以你可以默认为MyInternalClass,但如果你需要注入新的行为(例如,模拟):

internal class MyInternalClass : IMyInterface
{
}

public interface IMyInterface
{            
}

public abstract class MyAbstractClass
{
    protected IMyInterface myField;

    protected MyAbstractClass(IMyInterface required = null)
    {
        myField = required ?? new MyInternalClass();
    }
}

【讨论】:

  • 您还可以将内部类引用存储在私有字段中,然后提供一个受保护的属性将其公开为公共接口。这样做的另一个好处是允许您进一步限制对内部类的访问(通过接口),仅限于 MyAbstractClass 的派生者需要的访问。如果此接口以不同方式实现(例如,将其功能分解为两个辅助类而不是一个,它也会为您提供灵活性。)
  • @DanBryant:非常正确。好建议。
【解决方案2】:

你不能。如果MyAbstractClass 派生自外部类MyInternalClass,则需要知道。

如果你需要考虑这样的事情,设计可能需要返工。

【讨论】:

    【解决方案3】:

    您需要一个关键字来指定受保护的“和”内部,而不是受保护的“或”内部。不存在这样的关键字(从 C# 5.0 开始)。他们可以在以后的版本中添加它。

    这里有很多关于这个的话题。例如question 5596338

    补充:现在我想出了这个“解决方案”:

    public abstract class MyAbstractClass
    {
        protected class AccessMyFieldHelper
        {
            internal MyInternalClass this[MyAbstractClass mac]
            {
                get { return mac.myField; }
                set { mac.myField = value; }
            }
        }
        protected static readonly AccessMyFieldHelper AccessMyField = new AccessMyFieldHelper();
    
        private MyInternalClass myField;
    }
    

    myField 现在是private,但可以通过AccessMyField 访问它。因为它是一个索引器,所以您必须使用方括号[]

    你怎么看?这样可以做得更漂亮吗?

    【讨论】:

      【解决方案4】:

      将字段 myField 设为 internal protected

      您还必须将 MyAbstractClass 设为内部。如果它继承自内部类,它就不可能是公共的。如果类必须是公共的,那么就必须有一种解决方法:例如,创建一个接口来公开继承类所需的 MyInternalClass 功能。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-11-02
        • 2011-01-23
        • 1970-01-01
        • 1970-01-01
        • 2013-04-08
        • 2014-08-06
        • 2012-03-27
        • 2020-08-16
        相关资源
        最近更新 更多