【问题标题】:Design of method using ref to alter partially immutable class使用 ref 更改部分不可变类的方法设计
【发布时间】:2011-08-10 23:39:29
【问题描述】:

在我的项目中,我有一个头类,它代表系统内部一条信息的全局唯一键,例如它属于谁,它存在的时间等。在同一个头类中,我也有字段特定于给定数据实例的信息,例如谁创建了此版本的信息、创建时间、是否需要将新数据保存到数据库等。

这是一个将一些信息存储到数据传输类中并查询回来的示例。

var header = new IntvlDataHeader(
       datapoint: Guid.NewGuid(),
       element: Guid.NewGuid(),
       intervalUtc: DateTime.Now.Date);

package.StockData_Decimal(header, 5m);

decimal cloneData;
package.TryGetData_Decimal(ref header, out cloneData);

// header now refers to a different object, that could have different flags/information

请注意我是如何让 TryGetData_Decimal 通过引用传递标头变量的。 IntvlDataHeader 是一个类,如果在 TryGetData 中找到数据,则将引用更改为指向 IntvlDataHeader 的新实例,该实例除了具有相同的唯一键信息外,还具有特定的实例信息。

是否将键与实例特定信息相结合并使用 ref 参数作为 in 和 out 的糟糕设计?拆分另一个类以便有两个 out 参数并且没有 ref 参数会更好还是避免任何潜在问题?

方法的签名是public bool TryGetData_Decimal(ref IntvlDataHeader header, out decimal data)

【问题讨论】:

  • 哇,TryGetData_Decimal 真是太可怕了。为什么不使用泛型并使用类似于TryGetData<decimal> 的东西?
  • 由于几个原因,底层系统仅支持 5 种预定数据类型。我本来可以只使用 TryGetData,但是会有 15 个重载,从智能感知方式来看,只有 3 个名称中的类型的重载似乎更清晰。还有必须运行的类型特定代码,对于 String 和 Guid 数据类型,系统使用基于字典的压缩,它不用于其他类型。因此,使用泛型方法将需要另一个级别的间接性。在公共调用 *_Decimal 之后,有通用的私有方法在内部处理调用
  • 酷,很高兴知道这是故意的决定。感谢您告知我们。

标签: c# .net design-patterns architecture


【解决方案1】:

我认为您的TryGetData_Decimal 的命名具有误导性,如果您传入的ref 参数将在方法退出时指向一个新实例。 TryGetData_Decimal,对我来说,听起来像是 TryParse 方法在许多值类型上的变体(它有一个包含解析值的 out 参数 - 类似于 cloneData 参数)。

我想我不确定为什么标头对象必须指向一个新实例,所以我不确定我是否可以推荐一个设计。如果这是您需要做的,我认为如果您的 TryGetData_XXX 方法具有类似这样的签名,它可能更具可读性:

IntvlDataHeader ExtractValueAndGetNewInstance_Decimal(IntvlDataHeader header, out decimal cloneData)

其中标头被传入,但在方法退出时不会改变。该方法返回新实例,您可以在需要时使用它。我不会更改 cloneData - 我认为 out 参数是可以的,只要它们没有被过度使用。

我也会尝试将方法的名称更改为更有意义的名称。

我希望这会有所帮助。

【讨论】:

  • 我没有在示例中展示它,但是方法签名是public bool TryGetData_Decimal(ref IntvlDataHeader header, out decimal data),如果它完全找到该标头,它将返回一个真/假。然后只有当它返回 true 时,才会修改标头以指向具有可能不同标志和其他一些信息的不同实例
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-12
  • 2013-11-16
相关资源
最近更新 更多