继承vs类型标志

wda*_*avo 5 c# oop inheritance types

我做了一些搜索(也许我没有很好地描述我的问题)但是却找不到答案

假设你有以下POCO:

public class StandardObject
{
   public string A {get;set;}
   public string B {get;set;}
}
Run Code Online (Sandbox Code Playgroud)

在程序的其他地方有一些处理StandardObjects的逻辑.存在有时可能需要以不同方式处理StandardObject的情况.我们在创建StandardObject时知道这一点,但是当前属性都不能用于确定链中的这一点.一种方法是在StandardObject上添加和设置标志或类型枚举,并在处理对象时检查它.例如

if(standardObject.IsSpecial){...}

if(standardObject.ObjectType == StandardObjectTypeEnum.Special){...}
Run Code Online (Sandbox Code Playgroud)

这似乎不是最好的方法.

另一种选择是创建派生类:

public class SpecialObject : StandardObject { }
Run Code Online (Sandbox Code Playgroud)

所以现在我们可以检查类型,而不是检查属性.例如

if(standardObject.GetType() == typeof(SpecialObject)){...}
Run Code Online (Sandbox Code Playgroud)

(根据我们正在做的事情,类型检查可能会以不同的方式实现)

请注意,SpecialObject不会以任何方式添加或更改StandardObject.它本质上是同一个对象.这种方法的优点是更灵活(EG我们可以为SpecialObject添加一些额外的属性),但实际上它不会改变.它永远是完全相同的.

对我而言,继承似乎是更好的方法.类型标志看起来像代码气味,前进继承看起来更像是正确的OOP方法.我不确定的是,鉴于StandardObject和SpecialObject是相同的,这样做是不好的做法?或者有什么理由可以避免这种情况吗?

这里有一个类似的问题:

棋子层次结构设计:继承与类型字段

然而,大多数讨论似乎都集中在国际象棋问题而不是被认为是好的设计

编辑:

封装似乎是流行的解决方案.我避免封装的原因最好在下面的例子中描述:

  • StandardObject本质上是一个DTO
  • 有一个StandardObject列表.
  • 列表得到处理,StandardObject被序列化
  • 序列化数据通过任意数量的不同协议发送到某处
  • 其中一个协议要求在StandardObject为"特殊"时设置某些参数

鉴于"特殊"案例的附加逻辑只需要处理StandardObject的许多不同机制中的一个,这个逻辑似乎不属于StandardObject附近的任何地方.

Ran*_*pho 3

它们都是代码味道。如果必须在两个相关类型之间以不同方式完成特殊处理,请让它们都实现一些虚拟方法或接口操作,以允许它们处理特殊情况(如果没有必要,也可以不处理)。

  • 但逻辑在哪里执行呢?它是否包含在特殊对象中(在类本身或基类中),还是包含在对特殊对象中包含的*数据*进行操作的控制器对象中?如果是第一个,请遵循我最初的建议。如果是后者,请使用对象中的数据类型字段。应避免检查对象的类型并基于该类型进行分支,除非您正在使用一些无法重构的遗留代码。 (2认同)