Should I make the method virtual or abstract? - c#

I have an abstract class that does its own internal validation. It has another method that allows subclasses to do additional validation checks. Currently, I've made the method abstract.
protected abstract bool ValidateFurther();
However, I'm seeing quite a number of subclasses being forced to override it just to return true. I'm considering to make the method virtual.
protected virtual bool ValidateFurther() => true;
Is it bad to assume that validation is going to be fine in the abstract class? I'm worried that subclasses may not notice it and ended up not overriding it even when it is needed. Which is the more suitable approach here?

You could add another layer into your design.
public abstract class Base
{
protected abstract bool ValidateFurther();
}
public abstract class BaseWithValidation : Base
{
protected override bool ValidateFurther() => true;
}
If a significant subset of your inherited classes should just return true you can use BaseWithValidation to avoid having to repeat the code everywhere; for anything else use Base.

abstract method means you just want to define the behavior to be followed, and let sub classes do the implementation.
virtual method means you defined an method with initial implementation, but allow to be override.
So maybe you can explain you context more, then we can discuss it!

It's okay to make the method virtual and define a default implementation returning true.
protected virtual bool ValidateFurther() => true;
The difference between abstract and virtual is that that abstract methods defines only the signature of a method and the implementation is left to be implemented by the derived classes(similar to an interface). All child classes are required to implement the logic of an abstract method. You can see the documentation for more details.
Virtual on the other hand requires you to implement the logic and if needed you can override that method to add/extend the logic. And because you have default logic your child/derived classes are not required to override it. You can see the documnetation for more details.
Basically it is okay to implement the method as virtual and return true; by default.
FYI: From C# 8 you can have default implementations in the interfaces link

The short answer
If this class' (and all of its derived class') purpose does not always necessitate validation, then you should go with virtual, otherwise abstract.
In other words, is validation a cornerstone of this class' purpose? (yes = abstract, no = virtual)
I suspect that virtual is the better approach here, but not for the reason you're thinking it is. The rest of this answer elaborates on why your reasoning isn't the deciding factor here, and what actually is the deciding factor.
Your reasoning
I'm seeing quite a number of subclasses being forced to override it just to return true.
I suspect you're succumbing to the programmer's reflex: "I see this repeated and must write code to avoid this repetition!"
While that is generally a good approach, it can also be misapplied when you start applying this to things that happen to be the same rather than expressing the same functional purpose.
The example I tend to use to address that point is the following:
public class Book
{
public string Title { get; set; }
public DateTime CreatedOn { get; set; }
}
public class EmployeeJob
{
public string Title { get; set; }
public DateTime CreatedOn { get; set; }
}
There is definitely value to abstracting the CreatedOn property, as these entities are both audited data entities. The CreatedOn property is part of that audited entity, and its existence in both Book and EmployeeJob stems from these classes both being audited entities.
If a change is made to audited entities (e.g. they no longer track creation date), then that change needs to automatically persist to all audited entities. When you use shared logic, that automatically happens.
But does Title need to be abstracted into a shared logic? No. There is no functional overlap here. Yes, these properties have the same name and type, but they share no common logic whatsoever. They just happen to be equal to each other right now, but they are not tied to one another.
If a change is made to one Title property (e.g. it now becomes a Guid FK to a table of job titles), that change doesn't automatically reflect on the other (e.g. a book title would still just be a string). Implementing these Title properties using shared logic would actually cause a problem down the line instead of solve one.
In short: sometimes programmers seek more patterns than they need. Or if you allow me to quote Jurassic Park...
The deciding factor
I'm considering to make the method virtual.
Whether you make it abstract or virtual depends on one specific considerations (not DRY, as addressed above): Do you wish to provide a default implementation, or would you prefer to enforce that every consumer (i.e. derived class) evaluate the implementation of this method for themselves?
Neither of these are objectively better than the other, it's a matter of which fits best for you current scenario.
I'm seeing quite a number of subclasses being forced to override it just to return true.
I infer from this that you're essentially skipping validation in these classes, so in this case I would opt for the virtual approach since this class' (and all of its derived class') purpose does not always necessitate validation (again, that is my interpretation based on your explanation).
In other words, is validation a cornerstone of this class' purpose? (yes = abstract, no = virtual). You didn't specify your class or its purpose so I can't make that final call.

Related

I don't understand why it is wrong to test for possible interfaces in a base class

I have an abstract base class that will be used in hundreds of derived classes, including an additional abstract class.
There are at least 2 properties (let's call them Purpose and Description, both strings) that will be added to many (but not all) of the concrete derived classes, so I created interfaces (IPurposeful and IDescribable) to add them when needed. All is well so far.
I want a single method that I can call on all classes derived from my base class that will validate and update the Description property if it is indeed IDescribable, or just return true if it is not IDescribable. I'd like another similar method to validate/update the Purpose property.
I achieve this with a method in the base class that looks something like this:
protected bool CheckDescription(bool modify = false)
{
if (this is IDescribable ele)
{
var newDesc = GetCorrectDescription();
UpdateDescription(newDesc, ele.Description, modify);
return newDesc.Equals(ele.Description);
}
else
{
return true;
}
}
SonarQube marks the "this is IDescribable" check as a blocker (bad practice) and I am wondering why? The only other way I can think of to replicate this functionality would be to change the base method to this:
protected virtual bool CheckDescription(bool modify = false)
{
return true;
}
and then add this exact same method to potentially hundreds of derived classes:
protected override bool CheckDescription(bool modify = false)
{
var newDesc = GetCorrectDescription();
UpdateDescription(newDesc, Description, modify);
return newDesc.Equals(Description);
}
Now THAT would seem like bad practice.
EDIT: Changed the is/as pattern to remove redundancy
If your class may be IDescribable and may be IPurposeful, then give it sensible default implementations of those interfaces that may be no-ops and allow your descendant classes to override those implementations as required.
No type checks required. Just call the overridable methods and abide by their outcomes.
If your "optional" interfaces don't allow sensible no-op implementations, re-visit their definitions.
Now your base class can rely on the interfaces, rather than testing for them.
You may introduce runtime errors here - but the same can be said about base class methods that require a specific interface to be implemented that aren't compile-time checkable.
I decided to explore extension methods a bit more and found that for my particular needs they will work fine. I wanted to mark the original suggestion to look at extension methods as the correct answer but cannot seem to find a mechanism to do so.
Anyway, extension methods fulfill my requirements to be able to define a default algorithm in one place for most derived classes and override that behavior in specific derived classes only if/when necessary.
The one downside is that I cannot call the "base" implementation from within the "override" method. This may lead to a need to duplicate code in the future but thankfully for now I have not had that problem.

Explicit interface implementaion with second implementation

I was tracking down a bug and I found this in the Avalon Dock 2.0 source code:
public abstract class LayoutContent : LayoutElement, /* ... */, ILayoutPreviousContainer
{
// ...
[XmlIgnore]
string ILayoutPreviousContainer.PreviousContainerId
{
get;
set;
}
protected string PreviousContainerId
{
get { return ((ILayoutPreviousContainer)this).PreviousContainerId; }
set { ((ILayoutPreviousContainer)this).PreviousContainerId = value; }
}
}
ILayoutPreviousContainer has a member string PreviousContainerId { get; set; }.
What does this pattern accomplish? I understand that you could not get/set the PreviousContainerId from outside the inheritance subtree unless you first cast the LayoutContent to an ILayoutPreviousContainer. But I don't understand why you would want this.
Upon doing research about this pattern, I found this SO post which confused me some more. By implementing it this way, it is seemingly similar to having just a virtual property that would be implemented in a convoluted way:
public class SpecificLayoutContent : LayoutContent, ILayoutPreviousContainer
{
// override LayoutContent.PreviousContainerId since it casts 'this' to an ILayoutPreviousContainer
// which will then call this property
string ILayoutPreviousContainer.PreviousContainerId{ /* ... */ }
}
Am I missing something?
A protected property cannot implement an interface property, implicitly or explicitly. So if you want easy direct access from this class and derived classes, you want one protected property and another "hidden" property which explicitly implements the interface.
Looking at your example, one could consider switching roles of the two properties, such that the protected one was an auto-property, and interface-implementing one was referring to the auto-property (and not the other way around).
What alternative do you see? One could stick to a single property if that was made public (so implementing implicitly), but in that case the property would be exposed much more which is apparently not desired.
ILayoutPreviousContainer seems to be an internal interface. So as far as outside users of SpecificLayoutControl are concerned, the interface doesn't exist, and there is just the PreviousContainerId property defined on the class.
The usual rules apply for whether that should be protected or public. I won't expand on that, since it doesn't seem like that's what your question is about.
The class's authors have decided that the property should be protected. However, if it is protected, it cannot implement the interface's property, and although external users don't see that interface, internally that interface is required elsewhere. So, they implemented it like this, where one property merely forwards to the other.

How do I block the new modifier?

I have a property in a base class that I don't want overridden for any reason. It assigns an ID to the class for use with a ThreadQueue I created. I see no reason whatsoever for anyone to override it. I was wondering how I can block anyone from attempting to override it short of them changing its modifier.
private int _threadHostID = 0;
public int ThreadHostID
{
get
{
if (_threadHostID == 0)
{
_threadHostID = ThreadQueue.RequestHostID();
}
return _threadHostID;
}
}
Edit: totally forgot the language: C#.
Edit2: It is not virtual or overriding anything else so please no sealed.
First off: "Overriding" refers to virtual overriding. You are talking about creating hiding methods, not overriding methods.
I have a property in a base class that I don't want hidden
You are free to want that, but you are going to have to learn to live with the disappointment of not getting what you want.
I see no reason whatsoever for anyone to hide it.
Then there won't be a problem, will there? If no one could possible want to hide it, then they won't hide it. You're basically saying "I have an object of no value to anyone; how do I keep someone from stealing it?" Well, if it is of no value, then no one is going to want to steal it, so why would you spend money on a safe to protect something that no one wants to steal in the first place?
If there is no reason for someone to hide or override your method then no one will. If there is a reason for someone to hide or override your method, then who are you to tell them not to? You are providing a base class; you are the servant of the derived class author, not their master.
Now, sometimes being a good servant means building something that resists misuse, is robust, and reasonably priced. I encourage people to build sealed classes, for example. Designing secure, robust, inheritable classes that meet the real needs of inheritors is expensive and difficult.
But if you are going to create a robust unsealed base class designed for inheritance, why try to stop the derived class author from hiding, if they have a reason to do so? It cannot possibly hurt the base class. The only people it could hurt are the users of the derived class, and those people are the derived class author's problem, not yours.
There is no way to stop member hiding. If you don't make it virtual or abstract, then a derived class cannot override it properly anyway, hiding isn't polymorphic.
If a derived class hides it using the new operator, then they are opening up problems for themselves as any code that decides to use a reference to the base class will not touch the derived member. So basically, all code that utilises the "base class"-ness of the type hierarchy will bypass all member hiding anyway.
The sealed keyword only works if a derived type overrides a base type and doesn't want it to be overridden further... not sure how it plays with the new operator though. Most likely the member hiding will still be allowed, but will still have the same direct-type problem.
Your task is done by not making the method virtual or abstract, if a person wants to hide members then they are responsible for anything that breaks because they decided to abuse the design.
I think you should not worry about this. If you don't write it as virtual then you are making clear that it is not intended to be overridden and in fact you will receive a warning if you will override it (without the "new" modifier):
Warning: [...] hides inherited member [...].
Use the new keyword if hiding was intended
If you have this fear you should worry about any method that you write in a non-sealed class. So the job for you is just make sure that the design of your class is consistent and clear and if someone wants to inherit it then should be not dumb to just go and redefine non-virtual properties/methods. You cannot completely shield yourself from others stupidity :).
As far as I can tell, you apparently can't do that on a property level. However, if you seal the class:
public class Base
{
public int ID { get; set; }
}
public sealed class Child : Base
{
/// blah
}
then ...
public class Grandchild : Child
{
public int ID { get; set; }
}
will throw an error on the class definition, so using new doesn't even come into play.
Not an exact solution to your problem, but it does keep others from extending or interfering with your API.
Does it actually matter if someone does put a 'new' implementation in? I'm assuming you will always be referring to the base class in any code using that property since that is where it is declared and since it's not override or virtual it won't polymorphically call up to a 'new' implementation anyway.

How to "properly" override a base class method?

Whenever i override a method of a base class, other than my implementation of this method, i seem to have 3 choices.
1) Call base.Method(), and then provide my implementation.
2) Provide my implementation and then call base.Method()
3) Just provide my implementation.
Recently while using a library i have realized few bugs that were introduced because of not implementing the method as expected by the library. I am not sure if that is bad on part of library, or something wrong in my understanding.
I will take one example.
public class ViewManager {
public virtual void Customize(){
PrepareBaseView();
}
}
public class PostViewManager {
public override void Customize(){
base.Customize();
PreparePostView();
}
}
public class PreViewManager {
public override void Customize(){
PreparePreView();
base.Customize();
}
}
public class CustomViewManager {
public override void Customize(){
PrepareCustomView();
}
}
My question here is that how could a child class know (without taking a look at base class implementation) which order (or option) is being expected by the parent class?
Is there a way in which parent class could enforce one of the three alternates to all the deriving classes?
how could a child class know (without taking a look at base class implementation) which order (or option) is being expected by the parent class?
There is no way to "know" this when you are subclassing and overriding a method. Proper documentation is really the only option here.
Is there a way in which parent class could enforce one of the three alternates to all the deriving classes?
The only option here is to avoid the issue. Instead of allowing the subclass to override the method, it can be declared non-virtual, and call a virtual method in the appropriate place. For example, if you want to enforce that subclasses "call your version first", you could do:
public class BaseClass {
public void Method() // Non-virtual
{
// Do required work
// Call virtual method now...
this.OnMethod();
}
protected virtual void OnMethod()
{ // Do nothing
}
}
The subclasses can then "override" OnMethod, and provide functionality that happens after "method"'s work.
The reason this is required is that virtual methods are designed to allow a subclass to completely replace the implementation of the parent class. This is done on purpose. If you want to prevent this, it's better to make the method non-virtual.
This is why I feel virtual methods are dangerous when you ship them in a library. The truth is you never really know without looking at the base class, sometimes you have to fire up reflektor, read documentation or approach it with trial and error.
When writing code myself I've always tired to follow the rule that says:
Derived classes that override the protected virtual method are not required to call the base class implementation. The base class must continue to work correctly even if its implementation is not called.
This is taken from http://msdn.microsoft.com/en-us/library/ms229011.aspx, however this is for Event design though I believe I read this in the Framework Design Guidelines book (http://www.amazon.com/Framework-Design-Guidelines-Conventions-Libraries/dp/0321246756).
However, this is obviously not true, ASP.NET web forms for example require a base call on Page_Load.
So, long and short, it varies and unfortunately there is no instant way of knowing. If I'm in doubt I will omit the call initially.
The short answer is no. You can't enforce in what order the child calls the base method, or if it calls it at all.
Technically this information should be included in the base object's documentation. If you absolutely must have some code run before or after the child class' code than you can do the following:
1) Create a non-virtual function in the base class. Let's call it MyFunction
2) Create a protected virtual function in the base class. Let's call it _MyFunction
3) Have deriving classes extend the _MyFunction method.
4) Have MyFunction call _MyFunction and run the code it needs to run before or after calling it.
This method is ugly and would require a lot of extra code, so I recommend just putting a notice in the documentation.
The requirements of the base class should be documented by the library designer.
This issue is the reason why some libraries contain mainly sealed classes.

Subclass check, is operator or enum check

A couple of friends was discussing the use of inheritance and how to check if a subclass is of a specific type and we decided to post it here on Stack. The debate was about if you should implement a abstract enum in the base class to be used for checking the type of the subclass, or if you should use the is operator.
Alt 1.
public abstract class Document{
}
public class PDF:Document{
}
Check: If (myobj is PDF)
Alt 2.
public abstract class Document{
public abstract DucumentType TypeOfDocument {get;}
}
public class PDF:Document{
public DucumentType TypeOfDocument { get{return DucumentType.PDF };}
}
public enum DucumentType{
PDF, Word
}
Check: If (myobj.TypeOfDocument == DucumentType.PDF)
The ones for Alt1. ment that Alt2 slightly breaks SRP, you don’t take advantage of OO, Your repeating the abstraction. Since inheritance is the hardest connection between classes you cannot avoid knowing of them, and if you must go thru with inheritance minimize the impact. Alt2 also breaks DRY
The ones for Alt2 ment that Alt2 will be removing type checking entirely and replacing it with the option of checking this enum instead. Removing all hard connections to all subclasses, and the value of the enum itself does not say anything about which concrete implementation thats currently beeing operated on.
Whats your opinion about the two alternatives?
No discussion of inheritance vs. composition etcetera, that’s another question!
Why do you need to know in the first place? I agree that it's occasionally necessary, but where possible you should make the Document type have appropriate abstract functionality to allow the specialization to be done through inheritance rather than the caller having to treat it differently.
I would only use the enum approach if different subclasses may share document types but withotu wanting to share an inheritance hierarchy. This would be pretty rare, IME.
IMO you should use the is operator.
It gives you the same result without tainting the (abstract) class code.
I've got a similar situation, except that in my case, the DocumentType enum needs to grow as various types are added. By using the Enum, type checking is much better, but it requires that the "generic" base class be recompiled every time a new DocumentType is added.
The alternative I'm currently pondering is to use an interface property to return the type as a STRING. It's not great for type checking, but the rest of my code has the necessary validation to prevent rogue DocumentType objects. I would prefer a different solution, but nothing comes to mind.

Categories