Alex Rivera | Logout

Does C# support inout parameters?

Asked 2013-05-02T07:56:04.347
21

In C#, I am using a StreamReader to read a file, line per line. I am also keeping the current line's number in an int, for reports of possible error messages.

Reading each line goes along with some tests (for instance, lines beginning with # are comments, and need to be skipped), so I am planning to place the whole reading procedure in a function, which will keep reading until it encounters a useful line, and then returns that line. If it encounters EOF it will simply return null.

I thought I was being clever when I defined this function as string read(StreamReader sr, out int lineNumber), but now it turns out that C# won't be able to do something like lineNumber++ inside that function. It assumes that the variable has not been assigned yet, probably because it has no way to know whether it has been assigned in advance of this function call.

So, the problem is simple: how can I specify that this variable is an inout parameter (I think that's the term; I've heard it being mentioned in the context of other programming languages)? Is this even possible in the first place? I am absolutely not going to make lineNumber a member of my class, so that is not an option.

Edit
Report

1 Answer

1

As everyone says, you can simply use ref.

I'm going to suggest an alternative approach, just so you are aware of it.

You could write a method that returned an IEnumerable<Line> where Line is a very simple class that just encapsulates a line of text and a line number:

public class Line
{
    public string Text;
    public int    Number;
}

Then your method to read the lines could look something like this:

public IEnumerable<Line> ReadLines(StreamReader sr)
{
    int number = 0;

    while (true)
    {
        string line = sr.ReadLine();

        if (line == null)
            break;

        ++number;

        if (wantLine(line)) // Some predicate which decides if you want to keep the line.
            yield return new Line{Text = line, Number = number};
    }
}

Then you could use it as follows:

public void Test()
{
    StreamReader sr = new StreamReader("Whatever");

    foreach (var line in ReadLines(sr))
    {
        if (line.Text == "SomeSpecialValue")
            doSomethingWith(line.Text, line.Number);
    }
}

This is more work to write, but I think it can result in clearer code, and it also has the advantage that the line number counter is entirely hidden inside ReadLines(). (It's not a member of your class in the sense that it is a field in your class; it's just a local variable in the method.)

answered 2013-05-02T08:13:53.620

Your Answer