2013-05-02 4 views
11

В C# я использую StreamReader для чтения файла, строки в строке. Я также сохраняю номер текущей строки в int для сообщений о возможных сообщениях об ошибках.Поддерживает ли C# inout параметры?

Чтение каждой строки сопровождается некоторыми тестами (например, строки, начинающиеся с #, являются комментариями и должны быть пропущены), поэтому я планирую разместить всю процедуру чтения в функции, которая будет продолжать чтение до тех пор, пока не будет встречает полезную строку, а затем возвращает эту строку. Если он встретит EOF, он просто вернет null.

Я думал, что был умным, когда я определил эту функцию как string read(StreamReader sr, out int lineNumber), но теперь выясняется, что C# не сможет сделать что-то вроде lineNumber++ внутри этой функции. Он предполагает, что переменная еще не назначена, вероятно, потому, что она не имеет способа узнать, была ли она назначена до этого вызова функции.

Итак, проблема проста: как я могу указать, что эта переменная является параметром inout (я думаю, что это термин, я слышал, что это упоминается в контексте других языков программирования)? Возможно ли это в первую очередь? Я не собираюсь делать lineNumber членом моего класса, так что это не вариант.

+4

определите его как ref больше здесь http://msdn.microsoft.com/ru -IN/library/14akc2c7 (v = vs.71) .aspx –

+1

Что вы ищете для параметров ref: http://msdn.microsoft.com/de-de/library/14akc2c7(v=vs.80) .aspx – Mecaveli

+2

Эквивалент 'inout' в C# является' ref'. 'out' также является удобным. Это то, что вы искали? –

ответ

11

В этом случае вам нужен параметр ref вместо out. С ключевым словом out ответственность за назначение/создание значения лежит в , вызывающем метод ; с ref он находится за пределами вызываемого метода.

Также см: When to use ref vs out

+0

Спасибо, вот что я искал. –

1

Используйте реф ключевое слово вместо отказа. Это заставит вызывающего абонента инициализировать аргумент перед вызовом.

От MSDN - ref (C#)

аргумента, переданного параметра реф сначала должен быть инициализирован. Сравните это с параметром out, аргумент которого не должен быть явно инициализирован перед передачей в параметр out.

1

реф является то, что вам нужно

MSDN

терпение параметр метода ключевое слово в качестве параметра метода вызывает метод для обозначения одной и той же переменной, которая была передана в метод. Любые изменения, внесенные в параметр в методе, будут отражаться в переменной , когда управление переходит обратно к вызывающему методу.

1

Как все говорят, вы можете просто использовать ref.

Я собираюсь предложить альтернативный подход, чтобы вы знали об этом.

Вы могли бы написать метод, который возвратил IEnumerable<Line> где Line является очень простой класс, который просто инкапсулирует строку текста и номер строки:

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

Тогда ваш метод, чтобы читать строки может выглядеть примерно так это:

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}; 
    } 
} 

Тогда вы могли бы использовать его следующим образом:

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

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

Это больше работы для написания, но я думаю, что это может привести к более четкому коду, и это также имеет то преимущество, что счетчик номеров строк полностью скрыт внутри ReadLines(). (Это не входит в ваш класс в том смысле, что это поле в вашем классе, это всего лишь локальная переменная в методе.)