简短的回答
如果这个类(以及所有派生类)的目的并不总是需要验证,那么你应该选择virtual
,否则选择abstract
。
换句话说,验证是否是这个类的核心目的? (是=抽象,否=虚拟)
我认为在这里使用virtual
是更好的方法,但原因并非您想象的那样。本回答的其余部分详细阐述了为什么您的推理不是决定因素,以及真正的决定因素是什么。
你的推理
我看到很多子类被迫重写它只是为了返回true。
我怀疑你正在屈服于程序员的反应:"我看到这个重复出现了,必须编写代码来避免这种重复!"
虽然这通常是一个好方法,但当你开始将其应用于那些恰好是相同而不是表达相同功能目的的事情时,它也可能被误用。
我经常使用以下示例来解决这个问题:
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; }
}
将CreatedOn
属性抽象化确实有价值,因为这些实体都是审计数据实体。 CreatedOn
属性是该审计实体的一部分,并且它在Book
和EmployeeJob
中的存在源于这些类都是审计实体。
如果对审计实体进行更改(例如,它们不再跟踪创建日期),则该更改需要自动持久化到所有审计实体。当您使用共享逻辑时,这会自动发生。
但是,Title
需要被抽象成共享逻辑吗?不需要。这里没有功能重叠。是的,这些属性具有相同的名称和类型,但它们根本没有共同的逻辑。它们只是恰好现在相等,但它们彼此之间没有联系。
如果对一个Title
属性进行更改(例如,它现在变成了作业标题表的Guid
FK),那么该更改不会自动反映在另一个属性上(例如,书名仍然只是一个字符串)。实现这些Title
属性使用共享逻辑实际上会在以后引起问题而不是解决问题。
简而言之:有时程序员会寻求比他们需要的更多的模式。或者如果你允许我引用《侏罗纪公园》
quote Jurassic Park…
决定因素
我正在考虑将该方法设置为虚拟的。
无论您将其设置为抽象还是虚拟,都取决于一个特定的考虑因素(不是DRY,如上所述):您是否希望提供默认实现,还是更喜欢强制每个使用者(即派生类)自行评估此方法的实现?
这两种方法都没有客观上的优劣之分,而是取决于哪种最适合您当前的情况。
我看到有相当多的子类被迫重写它只是为了返回true。
我从中推断出,在这些类中,您基本上跳过了验证,因此在这种情况下,我会选择使用virtual
方法,因为这个类(以及所有派生类)的目的并不总是需要验证(再次说明,这是基于您的解释进行的我的解释)。
换句话说,验证是否是这个类目的的核心?(是=抽象,否=虚拟)。由于您没有指定您的类或其目的,因此我无法做出最终决定。