问题
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. :)
回答1:
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
. Theprotected internal
accessibility level means protected OR internal, not protected AND internal. However, theinternal
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 onprotected
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.
回答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.
回答3:
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.
来源:https://stackoverflow.com/questions/4022359/abstract-class-design-why-not-define-public-constructores