使用ref来改变部分不可变类的方法设计

本文关键字:方法 不可变 ref 改变部 使用 | 更新日期: 2023-09-27 18:04:54

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

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

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)

使用ref来改变部分不可变类的方法设计

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

我想我不确定为什么头对象必须指向一个新的实例,所以我不确定我可以推荐一个设计。如果这就是你需要做的,我认为如果你的TryGetData_XXX方法有这样的签名,可能会更容易读:

IntvlDataHeader ExtractValueAndGetNewInstance_Decimal(IntvlDataHeader header, out decimal cloneData)

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

我也会试着把方法的名字改得更有意义一些。