抽象类设计:为什么不定义公共构造函数?

发布于 2024-09-29 06:20:47 字数 507 浏览 3 评论 0原文

看这里(抽象类设计):http://msdn.microsoft.com/en -us/library/ms229047.aspx

它说:

(1) 不要在抽象类型中定义公共或受保护的内部(Visual Basic 中的受保护朋友)构造函数。

在 C# 中,我们不是能够实例化抽象类。那么,在 C# 中为抽象类定义公共构造函数还重要吗?或者因为语义的原因而不为抽象类编写公共构造函数?

它还说:

(2) 在抽象类中定义受保护的或内部构造函数。

定义内部构造函数?在(1)中,它告诉我们不定义内部受保护的构造函数是因为“具有公共或受保护内部可见性的构造函数适用于可以实例化的类型”。为抽象类定义内部构造函数不会违反 (1) 中的规则吗?

提前致谢。 :)

Look here (Abstract Class Design): http://msdn.microsoft.com/en-us/library/ms229047.aspx

It says:

(1) Do not define public or protected internal (Protected Friend in Visual Basic) constructors in abstract types.

In C#, we are not able to instantiate an abstract class. So, does it still matter to define public constructors for abstract classes in C# ? Or not writing public constructors for abstract classes because of semantic meaning?

It also says:

(2) Do define a protected or an internal constructor in abstract classes.

Define internal constructors ?? In (1), it tells us that not defining internal protected constructors is because that "Constructors with public or protected internal visibility are for types that can be instantiated". Doesn't defining internal constructors for abstract classes break the rules in (1) ?

Thanks in advance. :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

网名女生简单气质 2024-10-06 06:20:47

让我们看一下每个案例。

推荐:

  • 受保护 - 最明显的情况 - 所有子类都可以调用构造函数,无论它们驻留在哪个程序集中(只要抽象基类本身 对他们可见)。

  • 内部 - 当您希望抽象类型公开可见,但不能公开继承时很有用。在这种情况下,您可能希望将所有非私有构造函数设为内部。只有与抽象基类相同的程序集中的子类才能调用构造函数 - 实际上,只有它们才能继承。另一个用例是,如果您想要一个仅对同一程序集子类可见的“特殊”构造函数。

  • private - 主要用于“脏工作”构造函数,当抽象类使用构造函数链接时,这些构造函数将成为抽象类的其他构造函数的目标。当所有构造函数都是私有的时,唯一的其他用途是仅允许嵌套类进行子类化,这些类确实可以访问包含类型的私有成员。 p>


不推荐:

  • 公共 - 没有用,其行为与受保护相同。无论如何,只有子类可以调用构造函数,因为基类是抽象的。

  • 受保护的内部 - 这也与受保护的没有什么不同。 受保护的内部可访问性级别意味着受保护或内部,而不是受保护和内部。但是,这里的 internal 修饰符没有任何作用 - 它不会阻止位于程序集外部的子类调用构造函数(假设抽象基类是公共的),因为它们可以依赖protected访问,也不允许非子类的相同程序集类型调用它(类型是抽象的)。

这里的关键点是,抽象类中的每个非私有构造函数都已经充其量受到保护。普通的internal修饰符加强了对谁可以调用构造函数的限制。 publicprotected inside 没有完成任何事情,因为它们似乎削弱了限制,但实际上并没有成功。

Let's look at each of the cases.

Recommended:

  • protected - The most obvious case - all subclasses can call the constructor, irrespective of which assembly they reside in (as long as the the abstract base-class itself is visible to them).

  • internal - Useful when you want the abstract type to be publicly visible, but not publicly inheritable. In this case, you would want to make all of the non-private constructors internal. Only subclasses within the same assembly as the abstract base-class would be able to call the constructors - effectively, only they would be able to inherit. Another use-case would be if you wanted a 'special' constructor that should only be visible to same-assembly subclasses.

  • private - Used mainly for 'dirty-work' constructors that are targeted by other constructors of the abstract class when it uses constructor-chaining. The only other use, when all the constructors are private, is to only allow subclassing by nested classes, which do have access to private members of the containing-type.


Not recommended:

  • public - Not useful, behaves identically to protected. Only subclasses can call the constructor anyway, since the base-class is abstract.

  • protected internal - This too is no different from protected. The protected internal accessibility level means protected OR internal, not protected AND internal. However, the internal modifier here serves no purpose - it doesn't prevent subclasses residing outside the assembly from calling the constructor (assuming the abstract base-class is public) since they can rely on protected access, nor does it allow same-assembly types that are not subclasses from calling it (the type is abstract).

The key point here is that every non-private constructor in an abstract class is already at best protected. The vanilla internal-modifier strengthens restrictions on who can call the constructor. public and protected internal don't accomplish anything because they appear to weaken restrictions, but don't really succeed in doing so.

不即不离 2024-10-06 06:20:47

在 C# 中,我们无法实例化抽象类。那么,在 C# 中为抽象类定义公共构造函数还重要吗?或者不为抽象类编写公共构造函数是因为语义意义?

正是如此。您不希望用户看到可访问的构造函数,但当他们调用它时,他们会收到编译错误。

定义内部构造函数?在(1)中,它告诉我们不定义内部受保护的构造函数是因为“具有公共或受保护内部可见性的构造函数适用于可以实例化的类型”。为抽象类定义内部构造函数不会违反 (1) 中的规则吗?

我相信规则 1 是关于 public 的,而 protected inside 规则 2 是关于 <代码>受保护和<代码>内部。所以两者之间没有交集。

n C#, we are not able to instantiate an abstract class. So, does it still matter to define public constructors for abstract classes in C# ? Or not writing public constructors for abstract classes is because of the semantic meaning?

Exactly. You don't want the user to see an accessible constructor, but when they call it, they get a compile error.

Define internal constructors ?? In (1), it tells us that not defining internal protected constructors is because that "Constructors with public or protected internal visibility are for types that can be instantiated". Doesn't defining internal constructors for abstract classes break the rules in (1) ?

I believe rule 1 is about public and protected internal rule 2 is about protected and internal. So there's no intersection between the two.

瑾兮 2024-10-06 06:20:47

几年过去了。我想我现在对这个问题有了更好的理解。因此,除了阿尼的出色回答之外,我还想添加一些更多的意见。

在 C# 中,我们无法实例化抽象类。那么,是吗
在 C# 中为抽象类定义公共构造函数仍然很重要

这对编译器来说并不重要,但对代码阅读器来说很重要。抽象类型中的公共构造函数对代码读者来说是误导(他们可能认为它们可以被实例化)。

定义内部构造函数??在(1)中,它告诉我们不定义
内部受保护的构造函数是因为“构造函数
公共或受保护的内部可见性适用于可以
实例化”。没有为抽象定义内部构造函数
类违反了 (1) 中的规则?

如果我们希望抽象类只能被同一个程序集中的子类继承,显然我们不能使用protected(否则可以在程序集外部继承)。现在我们有一些选项可供选择:

  • public - 如上所述,public 对代码阅读器来说是误导。不要使用它。

  • private - 我们希望抽象类可由同一程序集中的子类继承,而不仅仅是嵌套子类,因此 private 不起作用。

  • 受保护的内部 - 我们永远不需要它,因为它与受保护的没有什么不同。

  • 内部 - 这对代码读者来说是误导,但我们别无选择。我认为这是一种权衡

Years passed. I think I have better understanding of this question now. So I would like to add some more input besides Ani's excellent answer.

In C#, we are not able to instantiate an abstract class. So, does it
still matter to define public constructors for abstract classes in C#
?

It doesn't matter to the compiler, but it does matter to code readers. Public constructors in abstract types is misleading to code readers (they might think they can be instantiated).

Define internal constructors ?? In (1), it tells us that not defining
internal protected constructors is because that "Constructors with
public or protected internal visibility are for types that can be
instantiated". Doesn't defining internal constructors for abstract
classes break the rules in (1) ?

If we want the abstract class to be inheritable only by subclasses within the same assembly, obviously we cannot use protected (otherwise it can be inherited outside the assembly). Now we have some options to choose:

  • public - As mentioned above, public is misleading to code readers. Don't use it.

  • private - We want the abstract class to be inheritable by subclasses within the same assembly, not just by nested subclasses, so private won't work.

  • protected internal - We'll never need it because it's no different from protected.

  • internal - It is misleading to code readers, but we have no other choice. I would think it a trade-off.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文