2013-05-02 12 views
11

W języku C# używam StreamReader do odczytu pliku, wiersz po linii. Przechowuję również numer bieżącego wiersza w numerze int, dla raportów o możliwych komunikatach o błędach.Czy obsługa C# nie zawiera parametrów?

Czytanie każdej linii idzie w parze z pewnymi testami (na przykład linie zaczynające się od # są komentarzami i muszą zostać pominięte), więc planuję umieścić całą procedurę czytania w funkcji, która będzie kontynuowała czytanie do momentu, aż napotka przydatną linię, a następnie zwróci tę linię. Jeśli napotka EOF, po prostu zwróci null.

Pomyślałem, że byłem sprytny, kiedy zdefiniowałem tę funkcję jako string read(StreamReader sr, out int lineNumber), ale teraz okazuje się, że C# nie będzie w stanie wykonać czegoś takiego jak lineNumber++ wewnątrz tej funkcji. Zakłada on, że zmienna nie została jeszcze przypisana, prawdopodobnie dlatego, że nie ma możliwości sprawdzenia, czy została ona przypisana przed wywołaniem tej funkcji.

Problem jest prosty: jak mogę określić, że ta zmienna jest parametrem inout (myślę, że to termin, słyszałem, że jest on wymieniany w kontekście innych języków programowania)? Czy to w ogóle możliwe? Absolutnie nie zamierzam uczynić lineNumber członkiem mojej klasy, więc nie jest to opcja.

+4

zdefiniuj to jako więcej tutaj http://msdn.microsoft.com/pl -IN/library/14akc2c7 (v = vs.71) .aspx –

+1

Czego szukasz parametrów ref: http://msdn.microsoft.com/de-de/library/14akc2c7(v=vs.80) .aspx – Mecaveli

+2

Odpowiednikiem 'inout' w języku C# jest' ref'. 'out' jest również przydatny. Czy tego właśnie szukałeś? –

Odpowiedz

11

W takim przypadku potrzebny jest parametr ref zamiast out. Ze słowem kluczowym out odpowiedzialność za przypisanie/tworzenie instancji wartości leży w metodzie nazwanej ; z ref leży poza wywołaną metodą.

zobacz także: When to use ref vs out

+0

Dzięki, tego właśnie szukałem. –

1

Użyj słowa kluczowego ref zamiast out. Zmusi to wywołującego do zainicjowania argumentu przed wywołaniem.

Z MSDN - ref (C#)

argument przekazany do parametru ref musi najpierw zostać zainicjowana. Porównaj to z parametrem out, którego argument nie musi być jawnie zainicjowany przed przekazaniem do parametru out.

1

Aref co trzeba

MSDN

ref parametr metoda słów kluczowych na parametr metody powoduje, że metoda odnosić się do tej samej zmiennej, który został przekazany do metody. Każda zmiana wprowadzona do parametru w metodzie zostanie odzwierciedlona w tej zmiennej , gdy sterowanie przejdzie z powrotem do metody wywołującej.

1

Jak wszyscy mówią, można po prostu użyć ref.

Zamierzam zasugerować alternatywne podejście, abyś był tego świadomy.

można napisać metodę, która zwróciła IEnumerable<Line> gdzie Line jest bardzo prosta klasa, która właśnie oddaje wiersz tekstu i numer wiersza:

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

Następnie metoda czytać wiersze może wyglądać mniej więcej tak to:

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

Następnie można go używać w następujący sposób:

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

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

To jest więcej pracy do napisania, ale myślę, że może to skutkować jaśniejszym kodem, a także ma tę zaletę, że licznik numerów linii jest całkowicie ukryty wewnątrz ReadLines(). (To nie jest członek twojej klasy w tym sensie, że jest to pole w twojej klasie, to tylko lokalna zmienna w metodzie.)