使用ref表示参数将被修改

Lee*_*Lee 5 c# theory language-design

我理解 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;
  }
}
Run Code Online (Sandbox Code Playgroud)

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

我知道这稍微滥用了 ref 修饰符,因为上面的示例中实际上并不需要它,但是以这种方式使用它实际上会给我带来任何问题吗?

Jep*_*sen 7

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

bool AddItem(ref Entity someEntity)
Run Code Online (Sandbox Code Playgroud)

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

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

使用的后果ref

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