开发者

Abstract Class Design: Why not define public constructores?

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

It says:

(1) Do not define public or protected internal (Prot开发者_C百科ected 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. :)


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.


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜