使用ref表示参数将被修改



我知道ref意味着当方法返回时,提交的引用可能指向完全不同的对象。

然而,我喜欢ref修饰符的一点是,开发人员立即知道,当方法返回时,他输入的内容可能会有所不同,因为ref修饰符也是调用方所必需的。

采用一个简单的方法,从一个假设的ORM:

public Boolean AddItem(Entity someEntity)
{
  try
  {
    // Add item to database
    // Get Id of entity back from database
    someEntity.Id = *returnedId*;
    return true;
  }
  catch (DBException ex)
  {
    return false;
  }
}

该方法的任何调用方都可能不知道其实体是通过调用该方法更新的。然而,将someEntity作为ref参数,这向开发人员表明,他们提交的参数将有所不同,然后他们知道要深入研究文档/代码,以了解它是如何更改的,而没有他们可能从未想过要这样做的修饰符。

我知道这有点滥用ref修饰符,因为在上面的例子中实际上并不需要它,但这样使用它真的会给我带来任何问题吗?

我认为这是滥用。假设Entity是引用类型,则参数声明

bool AddItem(ref Entity someEntity)

指示该方法可能会将引用someEntity移动到"指向"一个完全不同的对象实例。

如果您所做的只是更改现有实例someEntity,则不要写入ref。相反,使用名称(方法名称和参数名称)和文档,以明确您将"变异"(更改)对象。示例名称(您可以选择更好的名称,因为您知道实际代码):AddItemAndUpdateEntityID

使用ref:的后果

  • 调用方必须使用一个变量。他不能使用属性、方法调用或表达式求值的返回值
  • 调用方必须使用确切的类型,他不能传递SpecificEntity,例如SpecificEntity源自Entity
  • 方法的逻辑必须准备好,以便其他线程(或您自己调用的其他方法)可以更改ref参数的标识。例如,如果您在方法的顶部检查someEntity == null,则在方法的稍后某个点,该点可能已更改,因为其他人可能已将引用移动到其他位置

然而,我喜欢ref修饰符的地方是,开发人员立即知道,当方法返回时,他输入的内容可能会有所不同

不,他们没有。

他们对ref修饰符的了解是,当方法返回时,该参数实际上可能引用了其他

将接受引用类型的方法更改为仅使用ref,以便给人一种错误的印象,这在任何方面都是无效的。

当然也有另一面;除了滥用ref来指示它不意味着什么之外,你已经失去了ref指示它含义的能力;我们必须检查代码,看看该方法是否真的在使用ref,否则就无法从一个方法调用到另一个方法,知道您是否仍在处理同一个对象。

最新更新