如何创建一个抽象类,但内部不是抽象的?

6
这在c#中是否有可能?这是我需要的确切情况: 他(用户)不能创建此类的实例。然而,我想能够在我的项目内创建这个类的实例。(因此:内部) 其他类应该可以继承它。 我想强制用户仅使用更大的Sound类。 重要的“但是”:如果我把它给了他,用户必须能够使用此类的实例,这就是为什么我不能只将其设为内部并完成它的原因。我也不能使它抽象,因为我想自己制作副本。我考虑过只给用户返回像IChannel这样的接口,但这并不能解决他不应该能够创建Channel实例的问题。如果他搜索,他仍然能看到这个类,如果他足够冒险,甚至会尝试创建一个实例。 但正如我之前提到的:我不能使它抽象,因为我需要在内部制作副本。
8个回答

8

您可以将构造函数声明为internal,将类本身声明为public。这样做应该(我认为)可以满足您的需求。


谢谢!很好,你这么问是个好事,因为我想了一下,如果接口是公共的,而Channel本身是内部的话,那么接口方法应该可以用。但是它会变得很丑陋:)(额外接口没有人需要或想要) - Blub
1
我不同意;如果我正在测试依赖于你的类的代码,我肯定希望有一个接口,因为在单元测试期间可以轻松地将接口存根。另一个使用接口的好处是它仅公开与您的类的公共使用相关的功能,这可能是您在类内部使用的公共方法的子集。 - Dan Bryant
最终我将其制作成了一个接口,因为抽象类Channel继承了其他构造函数,而这些构造函数在之前我没有考虑到。我不想增加额外的负担,而且出于其他原因,它也完美地实现了我的需求。有时候你就是幸运地做出了正确的决定 :) 例如:其他类为IChannel提供了实际的实现,这将是内部的。这很完美,因为你也不能创建一个接口的实例。 - Blub

6

一个 internal 构造函数难道不能解决这个问题吗?这样只有你的程序集可以创建实例,但是 用户 仍然可以自由地使用实例。


5

内部构造函数。


2

通过在构造函数上使用不同的修饰符,您始终可以控制实例的创建:

public class MyClass
{
    internal MyClass()
    {
    }
}

现在没有人能够实例化你的类,但如果你给他们一个实例,他们可以像正常情况下一样使用它。

2
只需将类的构造函数设为内部的即可?

1
正如其他人所提到的,你可以在公共类中拥有一个内部构造函数。
然而,我会向客户提供一个公共接口并使整个类成为内部的(如果你希望客户能够对其进行子类化,则可将其设置为抽象类)。这样他们将使用接口,这将使他们更容易地对其代码进行单元测试。这样做还将为您提供未来更改实现的灵活性。

0
我认为你想要的是一个具有受保护构造函数和内部工厂方法的公共类:public class with a protected constructor and an internal factory method。
public class MyClassWhichIsAbstractExceptForMe
{
    // Allow derived classes but prevent public construction.
    protected MyClassWhichIsAbstractExceptForMe()
    {
    }

    // Allow internal construction
    internal static MyClassWhichIsAbstractExceptForMe Create()
    {
        return new MyClassWhichIsAbstractExceptForMe();
    }
}

我也温和地建议进行设计审查。正如其他人所指出的那样,这似乎相当奇怪。


0

使用内部作用域的构造函数将允许您在同一程序集或任何其他程序集中创建子类,只要您已经使内部可见。但是,它将防止在其他程序集中创建子类,因为每个从另一个类派生的类都需要调用基类上的构造函数。如果您的构造函数基于其作用域不可用,则会阻止其他人从您的类派生。

通常,我不喜欢这种思维方式。作为开发人员,发现我正在使用的API的开发人员认为他知道我想如何使用它真的很烦人。是的,如果必须隐藏实现的内部细节,但请允许我扩展API以执行我需要的操作(而您没有考虑到),并且不要让我跳过这些步骤。

哦,对了,请为其创建一个接口并将其用作返回值。从长远来看,这将使我的和您的生活更轻松,此外还可以使在我的单元测试中模拟您的代码变得更加容易。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接