【问题标题】:Prevent Exposure of Base Classes (Abstract Classes)防止暴露基类(抽象类)
【发布时间】:2019-03-21 09:42:01
【问题描述】:

因此,我查看了许多相关问题,但似乎没有一个完全适合。至少在我目前的理解中不是。由于这是一个简单的问题,我将简明扼要地提出我的问题和代码。

我有五个班级:

internal class A
internal abstract class B : A
internal abstract class C : B
public class D : C
public class E {
    public void X(C c) { }
}

在public 方法中使用参数C 时存在明显的可访问性问题。我需要访问类D 而不暴露类C。我相信这可能是由于 abstract 关键字的性质,以及我使用它的最少经验。

迄今为止,我从未有过创建abstract 类的已知需求,这是我第一次在这个级别上处理它。据我了解,在这种情况下,只要我记得正确实现所有内容,就没有必要使用 abstract 类。


我的问题

  • 我是否应该创建一个类 F,它有一个私有实例 D 作为一种包装以防止暴露?
  • 什么是使用 abstract 的充分理由,因为我不认为这段代码是一个很好的例子。
  • 还有哪些其他方法可以在不暴露 A、B 或 C 的情况下暴露 D?

注意事项

  • 我正在尝试对当前的更改进行手术。
  • 最初所有课程都是私有的。

我看过很多相关的帖子(这里有一些):

【问题讨论】:

  • 我不确定这里有什么奥秘。您正在创建一个 public 类并让它派生自 internal 类。这与abstract 关键字无关。你正在尝试做一些没有意义的事情。可以这样想:你告诉编译器你想要基于焦糖的糖果,但糖果不能包含焦糖。
  • @JuanR 感谢您指出我的逻辑中的错误;与这段代码斗争了很长时间,我的思绪开始围绕它融化。我已经澄清了帖子。
  • 不用担心。为什么你不想暴露A、B或C?如果你不想暴露它们,为什么D是从它们派生出来的?
  • @JuanR A、B 和 C 被多个类使用(并且可以),但代码正在转换为某种 API,订阅者不应有权访问那些课。这个想法是使 API 尽可能简单,而不是暴露在后台使用的工具。 D 由于特定方法(例如自定义处置等)目前需要它们。所有代码都是几十年前编写的,目前专注于单一任务;我目前的任务是将其重构为更简单和可重用(只有简单的东西应该是可重用的)。
  • abstract 关键字表示您有一个对象是什么的基类(或抽象),但不一定是所有细节。然后具体(派生)类成为实际的实现。某些属性或方法可能由所有派生类共享,因此它们可以存在于基类中。

标签: c# inheritance abstract


【解决方案1】:

您可以使用界面来隐藏详细信息。考虑一下:

//This represents the contract, regardless of the underlying object
public interface ISomeObject
{

}

//Class is internal, but implements the interface
internal class A : ISomeObject { }
internal abstract class B : A { }
internal abstract class C : B { }

//Class D is still internal
internal class D : C { }

public class E
{   
    //Method uses interface, which is public     
    public void X(ISomeObject c) { }

    public ISomeObject DoSomething()
    {
        //Create internal class, return it for use (as a contract)
        return new D();
    }
}

示例用法:

var e = new E();
var result = e.DoSomething();
e.X(result);

这是可行的,因为从外部角度来看,您处理的是公共合同,而不是实际的实施。

【讨论】:

    猜你喜欢
    • 2012-07-29
    • 1970-01-01
    • 2011-03-30
    • 1970-01-01
    • 2017-10-30
    • 2018-07-11
    • 1970-01-01
    • 1970-01-01
    • 2020-06-02
    相关资源
    最近更新 更多