2

Is using ref is bad programming practice? I am doing some refactoring of my old code which actually uses ref a lot. I have turned on code analysis with Microsoft All Rules set and rules say that "Do not pass types by reference"

Cause: A public or protected method in a public type has a ref parameter that takes a primitive type, a reference type, or a value type that is not one of the built-in types.

Why is it really bad? Can I use them in my private methods or internal methods? Using ref in private/internal methods will be good programming practice or nor?

Edit: Here is some samples,

public void DoAutoScrollReverse(Rectangle rectangle, int xPosition, int yPosition,
    ref int deltaX, ref int deltaY)
{
}

public bool GetPointCoords(Graphics g, Point pMouse, DisplayBlock2D aBlock,
    ref Point3MD pt, ref DisplayPoint2D 2dPoint, ref double gapPos)
{
}

What is happening inside these function is that they are being initialized, set, or whatever.

Update: Why am I using ref? Well actually I am not. Its old code which I need to refactor. I got rid of some of the methods, but complex functions like in second example given I cannot. There is a function which returns bool (tells operation successful or not) and has 3 ref values of different objects. What should I do here? make it private/internal (Is using ref in private/internal good practice?)

fhnaseer
  • 7,159
  • 16
  • 60
  • 112
  • 2
    plz read http://www.yoda.arachsys.com/csharp/parameters.html as well answers in http://stackoverflow.com/questions/1981916/c-sharp-ref-keyword-usage – C Sharper Jul 22 '13 at 05:12
  • 2
    We don't have nearly enough context to answer this. `ref` isn't *always* bad, but it's usually worth avoiding and is often misunderstood. If you could give us an example of where you're considering using it, that would help a lot. – Jon Skeet Jul 22 '13 at 05:14
  • @JonSkeet added some sample method definitions, – fhnaseer Jul 22 '13 at 05:23
  • @FaisalHafeez: Well in the first case it looks like you should return some sort of vector instead, which combines `deltaX` and `deltaY`. We don't really know what the second method is trying to do, which makes it hard to say what the solution should be. – Jon Skeet Jul 22 '13 at 05:27
  • The question you have to answer is ***why*** you're using `ref`. And then you'll probably have the answer to this question. If not, please be sure to [edit] this question and let us know why you're using it. – Cody Gray - on strike Jul 22 '13 at 05:42
  • @CodyGray I am trying to get rid of ref. Well its actually old code which I am refactoring. I have updated my question. – fhnaseer Jul 22 '13 at 06:08
  • @JonSkeet yeah, first example can be refactored in that way by returning a Point object. But what for complex methods? – fhnaseer Jul 22 '13 at 06:09
  • 2
    @FaisalHafeez: No, you shouldn't return a *point* from the first version - a point isn't a vector, and given the names `deltaX` and `deltaY`, you really do mean a vector (the difference between two points). "Complex methods" is very vague - you'd need to give very specific examples. Sometimes it's worth creating a type for the output (and prefer `out` to `ref` where feasible anyway, for clarity) and sometimes it means the method is just doing too much. – Jon Skeet Jul 22 '13 at 06:28
  • The problem with ref, from my experiences with it, is that programmers tend to use it as a shortcut to proper class designs. (i.e. passing a variable as ref to multiple functions for variable sharing, rather than using class properties). typically, many bugs get induced this way, especially if code is either intentionally or unintentionally run asynchronously. – Claies Jul 23 '13 at 15:13

1 Answers1

2

I think it is better to do not use ref unless it is really necessary. It can lead to errors that are hard to detect if local variables can be changed in other methods.

You examples can be easily rewrite so you don't need to use ref anymore.

public void DoAutoScrollReverse(Rectangle rectangle, int xPosition, int yPosition,
ref int deltaX, ref int deltaY)
{
}

Create a small class:

public class Delta
{
    int X { get; set; }
    int Y { get; set; }
}

Without ref:

public Delta DoAutoScrollReverse(Rectangle rectangle, int xPosition, int yPosition)
{
    return new Delta(deltaX, deltaY);
}

Now it is also more clear that you are returning something and what you are returning.

Alex Siepman
  • 2,499
  • 23
  • 31