Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using ref to indicate parameter will be modified

I understand that ref means the reference submitted may point to an entirely different object when the method returns.

However what I like about the ref modifier is that the developer immediately knows what he put in may be somehow different by the time the method returns, as the ref modifier is also required caller side.

Taking a simple method, from a hypothetical 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;
  }
}

Any caller of the method may not know that their entity was updated by calling the method. However making someEntity a ref parameter, it indicates to the developer that their submitted parameter will be different, they then know to dig into the documentation/code to find out how it is changed, without the modifier they may have never thought to do so.

I know this is slightly abusing the ref modifier, as it is not actually required in the example above, but will using it this way actually cause me any problems?

like image 775
Lee Avatar asked Feb 11 '23 11:02

Lee


1 Answers

I think it is abuse. Assuming Entity is a reference type, the parameter declaration

bool AddItem(ref Entity someEntity)

indicates that the method might move the reference someEntity to "point to" an entirely different object instance.

If all you do is mutate the existing instance someEntity, do not write ref. Instead, use names (method name and parameter name) and documentation that make it clear you will "mutate" (change) the object. Example name (you can choose better names since you know the actual code): AddItemAndUpdateEntityID

Consequences of using ref:

  • the caller must use a variable. He cannot use the return value from a property, method call or expression evaluation
  • the caller must use the exact type, he cannot pass a SpecificEntity, say, where SpecificEntity derives from Entity
  • the logic of your method must be prepared that other threads (or other methods you call yourself) may change the identity of the ref parameter. For example, if you check if someEntity == null in the top of your method, at a later point in your method that might have changed because someone else might have moved the reference to point elsewhere.
like image 132
Jeppe Stig Nielsen Avatar answered Feb 13 '23 02:02

Jeppe Stig Nielsen