Abstract Class Design: Why not define public constructores? - c#

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. :)

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.

Related

Limit scope of method for child implementations

I hope this isn't a duplicate but I can't find one via Google or SO search. If I want to force the accessibility for a method's implementation of an overridden method to be protected, is my only option to either create as abstract or protected virtual? I know that interfaces specify the declaration but leave the accessibility/scope to the class implementation but I'd like to be sure.
I'd like to know/be certain of if the only way to limit the scope of a method is via a abstract \ protected virtual to give semantics of "this applies to the class implementation or the child override implementation".
A code sample to illustrate. I know I can do the following and limit the scope of an implementation like so;
public class BaseClass
{
protected virtual void OnlyMeOrChildrenCanDoAction()
{
// leave empty as current class is structural/conceptual
// but child instances may need it
}
}
By doing the above I guarantee that child implementations can only override OnlyMeorChildrenCanDoAction()as protected but not public.
But is there another way of limiting to protected without resorting to abstract or protected virtual? An example of creating a method like this is Object.Finalize() as seen here.
Or, to invert the question somewhat, why would you create a method as protected virtual unless to ensure that any implementations were limited in scope? Or is there another way to do the same?
I think you're misunderstanding the meaning and use of virtual. You can only override a method in the parent class if it is declared virtual. The override method in the child class must have the same visibility as the method in the parent class.
Implementations of methods declared in interfaces are always public.
Declaring a method abstract has the same effect as declaring it virtual, except you do not implement it in your class and any concrete classes that derive from your class must implement it.
Technically, the compiler will not allow you to change the access modifiers of a method when overriding it from the parent, so the answer to the question is that by declaring a method as protected within a class, you are only making it available to derived classes (whether abstract or not is a separate concern and doesn't bear on the access level).
Keep in mind, however, that derived class would be free to expose the function in some other way such as calling the protected method from a public one and there is no way to prevent that.
As far as "why" you would have a protected abstract member, a great example can be seen in many implementations of the Template Method pattern. You may have an abstract base class that describes the structure of an algorithm and leave the specific steps of what happens inside the boundary of each step to derived classes. In this case, one way to implement would be to declare the base class as abstract, have a public method serve as the "entry point" for the algorithm, and define specific methods used within the algorithm as protected abstract methods to lay out what the responsibility of derived classes will be. This pattern does a nice job of leaving public only those things that are intended to be consumed by the world, but can present some challenges from a unit testing perspective which are sometimes addressed by raising the visibility of the helper methods from protected to internal.
You cannot use the c# language to prevent a derived class from implementing a public version of OnlyMeOrChildrenCanDoAction. Even if you mark it as protected virtual, the derived class can use the new keyword to cover the method and change its accessibility. For example:
public class BaseClass
{
protected virtual void OnlyMeOrChildrenCanDoAction()
{
// leave empty as current class is structural/conceptual
// but child instances may need it
}
}
public class DerivedClass : BaseClass
{
public new void OnlyMeOrChildrenCanDoAction()
{
Console.WriteLine("This is public.");
}
}
public class Program
{
public static void Main()
{
var b = new BaseClass();
//b.OnlyMeOrChildrenCanDoAction(); //Will not compile
var d = new DerivedClass();
d.OnlyMeOrChildrenCanDoAction(); //Look! It's public!
}
}
Output:
This is public.
Code available on DotNetFiddle.
If you want to protect the caller from calling OnlyMeOrChildrenCanDoAction, your best bet is for the caller to use only interfaces. If OnlyMeOrChildrenCanDoAction isn't in the interface, there is no way a caller could call it, even if a derived class decided to expose it as a public class member. This is good SOLID design anyway.
On the other hand, if you're not so much worried about the caller as you are worried about your own development team doing bad things, perhaps your best option is to use FxCop or some other source code rules engine integrated into your continuous build process. Developers could still add the method but you could set up a rule to cause it to fail the build if they do so.

Is there something inherently wrong with giving Abstract Classes a Constructor?

http://msdn.microsoft.com/en-us/library/ms182126.aspx
Microsoft Design Guidelines say that Abstract Types should not have a Constructor.
To me, it seems very plausible that most classes that derive from an abstract class will have a constructor very similar to, if not identical to, its base.
If for no other reason but to follow DRY, is it really terrible to have abstract classes with Constructors if it means that all your derived classes now only need to put
public DerivedClass()
: base()
{
}
Or is there something that I am missing?
There's nothing to prevent you from doing that but by definition abstract classes are those that cannot be instantiated. So if you create a constructor, make it protected, not public otherwise your class won't meet the definition of abstract.
The guideline you mentioned further explains:
Cause: A public type is abstract and has a public constructor.
and
Rule description: Constructors on abstract types can be called only by derived types. Because public constructors create instances of a type, and you cannot create instances of an abstract type, an abstract type that has a public constructor is incorrectly designed.
How to Fix Violations: To fix a violation of this rule, either make the constructor protected or do not declare the type as abstract.

Internal Interfaces & Classes

I'm refactoring some code I didn't write, that contains business logic and proprietary algorithms I don't want to expose. All the code is currently marked as internal; for testing purposes, and to ensure I don't break existing clients/services, I wanted to switch them to use interfaces, and implement those interfaces.
I've marked my classes as internal and their members as protected internal, and my interfaces as internal, but to use the internal interfaces, I've had to make several of my properties public.
I believe, and with some limited testing, seemed to have proven that only friend assemblies, and classes in my assembly, can use these internal interfaces and classes.
As long as both the class, and interface remain internal, even if some of the methods and the properties are marked public, will they be exposed at all?
It doesn't seem so, but I'm looking for anything I might have missed.
If you mean protected as in a using assembly can't directly use them, then yes, if the interface and class are marked internal, then they won't be visible outside the assembly. Think of the access level on the interfaces and members as being separate locks to get through.
If you can see the interface at its access level, then you can store a reference to it, and then if you can see the properties/methods at their access levels, then you can call/set/get them.
Keep in mind, though, as #phoog points out that protected internal is a bit looser than internal.
All this said, if your internal class implements a public interface, and those properties are part of a public interface as well, they could be visible... But that's really getting obscure...
public interface IVisible
{
string VisibleProperty { get; set; }
}
internal class InvisibleClass : IVisible
{
public string VisibleProperty { get; set; }
}
In the above, you could refer to the class InvisibleClass through an IVisible reference in a different assembly if you could find a way to construct or receive a reference to it (for instance, if it were returned from a factory method inside of the original assembly).
All this aside, if your question is that you want to avoid them from being examined through a decompiler, reflection, etc, that's a different question...
A public member is only as accessible as its type ("Normally, the accessibility of a member is not greater than the accessibility of the type that contains it. However, a public member of an internal class might be accessible from outside the assembly if the member implements interface methods or overrides virtual methods that are defined in a public base class.").
Don't be bitten by the protected internal problem, though: a protected internal member is available to derived classes outside the assembly.
References:
Accessibility levels: http://msdn.microsoft.com/en-us/library/ba0a1yw2.aspx
Access modifiers: http://msdn.microsoft.com/en-us/library/ms173121.aspx
You're right. Since you can't access internal classes from outside (apart from friend assemblies), you can't access any of its methods either, even if they're public.
You could access an internal class from outside it it has a public base class or implements a public interface. But you could only access the public methods in that class that are both in the base class (or interface) and overridden in the sub class (so the method should also be virtual or part of an interface - which also makes it virtual). For this, you'd have to obtain an instance to the class referenced by a super class (or interface) variable.

Relevance of 'public' constructor in abstract class

Is there any relevance of a 'public' constructor in an abstract class?
I can not think of any possible way to use it, in that case shouldn't it be treated as error by compiler (C#, not sure if other languages allow that).
Sample Code:
internal abstract class Vehicle
{
public Vehicle()
{
}
}
The C# compiler allows this code to compile, while there is no way i can call this contructor from the outside world. It can be called from derived classes only.
So shouldn't it allow 'protected' and 'private' modifiers only.
Please comment.
There's no reason for a public constructor for an abstract class. I'd assume that the reason that the compiler doesn't complain is as simple that they just didn't spend time covering that since it really doesn't matter if it's public or protected.
Inside an abstract class, for an instance constructor, modifiers public, protected internal, and protected are all equivalent. Then internal is more strict than them, and private is the most strict access.
If all instance constructors are private, only classes nested inside the class in question can inherit from it.
Note: If no instance constructors are given for a non-static class, then the compiler will generate one by itself. That's a constructor taking zero arguments. If the class is abstract, that auto-generated constructor is protected. Otherwise it is public.
The only situation I can think of where it makes a difference if an instance constructor of an abstract class is public or protected, is when you use reflection. As an example, saying
ConstructorInfo[] ctors = typeof(Vehicle).GetConstructors();
will give an empty array if the sole constructor is protected, and a length-1 array if it's public. But of course there are overloads that specify BindingFlags, so this is not a problem, just something to remember if one uses reflection.
Dupe: there is another question on SO just like this: Abstract class constructor access modifier
The answers on that question come down to the same thing in the end: it does not really matter if you declare it protected or public.
Also there seems to be some discussion about it in literature (e.g. in Framework Design Guidelines). This is referenced in this blogpost: Good design or bad design of abstract class?
Yes, a public ctor on an abstract class is meaningless and a bit misleading as it will behave as protected in that only derived classes may call it.
A private ctor will have little meaning outside of interesting edge cases.
A protected ctor would make sense if required by derived classes.

internal abstract methods. Why would anyone have them?

I was doing some code review today and came across an old code written by some developer. It goes something like this
public abstract class BaseControl
{
internal abstract void DoSomething();
}
If you have a derived class within the same assembly, it would work
public class DerivedControl : BaseControl
{
internal override void DoSomething()
{
}
}
But deriving the base class in a different assembly would give compile time error
DerivedControl does not implement inherited abstract member 'BaseControl.DoSomething()
That got me thinking. Why would anyone declare a method as internal abstract ?
The original programmer wanted to make a derived control available to client code. But prevent the client from inheriting and messing with the virtual method. That's not a bad idea, it is usually easy to break a base class by overriding a method and doing something like forgetting to call the base class method.
One obvious case is where the method receives or returns an internal type. For example, the core methods of the WPF Transform classes process some internal interop types, which WPF doesn't expose as part of its public API. Because the signature includes internal types, the method can't be public or protected. And yet clearly it's appropriate (necessary!) for the various Transform classes to work polymorphically. Therefore the base methods in Transform/GeneralTransform have to be internal.
Another, but related reason is to prevent external derivation. After all, the WPF architects could have exposed a "safe" version of the internal interop types in a protected abstract method, so that users could create their own Transform classes. They didn't because they didn't want to have to cope with the ways that people might use that capability, e.g. creating non-affine transforms. Allowing external derivation would have made the job of other classes in WPF hugely more complex, so the architects decided to allow only "approved" derived classes by making an abstract method internal.
My initial reaction was that there is no good reason, if you want to prevent external inheritance then you should mark the class internal. But that means that the class is totally hidden to other assemblies.
I suppose this method prevents external inheritance while retaining visibility.
By defining a method as internal abstract you want to make sure that only the class in the same assembly can have its implementation for your method.
now if you distribute a dll of it this will avoid the client to inherit and mesup the implementation.

Categories