2013-05-02 120 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/zh-cn/ -IN/library/14akc2c7(v = vs.71).aspx – 2013-05-02 07:58:37

+1

你在找什麼參考參數:http://msdn.microsoft.com/de-de/library/14akc2c7(v=vs.80) .aspx – Mecaveli 2013-05-02 07:58:42

+2

c#中'inout'的等價物是'ref'。 'out'也是一個方便的。那是你在找什麼? – 2013-05-02 07:59:34

回答

11

在這種情況下,您需要ref參數而不是out。使用out關鍵字,分配/實例化一個值的責任在 調用 調用的方法內;與ref它位於被調用的方法之外。

另見:When to use ref vs out

+0

謝謝,這就是我一直在尋找。 – 2013-05-02 08:01:33

1

使用ref關鍵字,而不是出去。這將強制調用者在調用之前初始化參數。

MSDN - ref (C#)

一個參數傳遞給ref參數必須先被初始化。 將此參數與輸出參數進行比較,在傳遞給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()內部的優點。 (它不是班級的成員,因爲它是你班上的一個領域,它只是方法中的一個局部變量。)