2017-05-03 99 views
-6

我有一段代碼,它具有標題中所述的一個方面。在聲明之前使用但在使用之後聲明的變量

public string ReplaceCC(Match m)// Replace each Regex cc match with the number of the occurrence. 
{ 
    i++;//it's used in function before declaration 
    return i.ToString() + i.ToString();  
} 

public static int i=0; 
} 

我認爲我腦海中有一個編譯/聲明的混亂。這裏的問題是什麼?

+0

對於試圖瞭解您的問題而言,這是非常草率的,請修改問題併發布與您遇到的問題相關的所有相關代碼,此外,請編輯解釋並將其作爲真正的問題在哪裏調用'ReplaceCC()'? – MethodMan

+1

變量是靜態的。這意味着它是在使用之前創建的。 https://msdn.microsoft.com/en-us/library/79b3xss3.aspx – Steve

+1

@Steve即使它是一個實例變量,代碼也會編譯得很好(儘管它的行爲會有所不同)。 – Servy

回答

0

雖然我可以感知,這是莫名其妙,你的東西是在聲明它的代碼的順序。有一個在下面的代碼看看:

class Program 
{ 
    public Program() 
    { 
    } 

    public void myFunc() 
    { 
     canIAccessIt = 10; 
    } 

    public int canIAccessIt = 0; 
} 

以上,在C語言背景(忽略其不存在C類部分)上面的代碼中任何人都可能進入一個以爲myFunc函數試圖訪問一個變量canIAccessIt甚至在它被宣佈或進入範圍之前。

C#.Net世界中的變量範圍並不是那種方式。一個類級變量(又名成員變量)與對象的實例相關聯,並且從創建對象到時間對象被銷燬或垃圾​​收集時進入範圍。

就像在上面的情況一樣,人們可能會認爲canIAccessIt變量可能沒有成爲現實,因爲它在myFunc方法下被聲明。這是所以不是

當我上面的代碼是由C#編譯器編譯它成爲你的* .dll文件裏面寫MSIL(Microsoft中間語言)這樣的事情這是C#項目建設過程中的輸出:

class Program 
{ 
    public int canIAccessIt; 
    public Program() 
    { 
     canIAccessIt = 0; 
    } 

    public void myFunc() 
    { 
     canIAccessIt = 10; 
    } 
} 

注意:上述MSIL代碼僅供參考,以便您能理解它。 MSIL代碼看起來比這更奇怪,因爲它必須由CLR而不是用戶或程序員來理解。

因此,對於編譯器來說,全局變量在類中聲明的位置並不重要。只要它在你的類的開頭({)和關閉大括號(})的內部,那麼它的初始化將移到你的類的構造函數中。一個類的構造函數是每當你創建一個類實例時被調用的第一個方法。它發生的那一刻你的變量就會變成現實(被初始化和初始化),併成爲在範圍內被myFunc方法所使用。

在你的類中,唯一與i變量不同的是它是靜態的,所以它的初始化將移動你的類的靜態構造函數,而不是你類的實例構造函數。您的i變量的生命週期和範圍與您的類的Type實例(又名靜態實例)相關聯。

所以每當你初始化類第一時間能在這裏打電話給你ReplaceCC方法是事件的順序:

  1. 實例構造函數被調用。
  2. 靜態構造函數被調用 - 它初始化您的靜態變量i
  3. 然後你在對象實例上調用ReplaceCC方法,當我已經實例化和初始化。

你也可以看看this回答哪個秒我的想法。

0

你正在申報功能範圍之外的變量,作爲靜態類變量:

public static int i=0; 

該變量初始化你第一次嘗試使用它,在創建靜態實例時。

0

你在範圍外聲明變量,它是一個全局變量。

例如:

public class Person 
{ 
    public Person(string name) 
    { 
     this.Name = name; 
    } 

    public string Name { get; set; } 
} 

此代碼聲明變量名稱在人的根。

-2
public string ReplaceCC(Match m) 
{ 
    i++;//Here your adding 1 to the existing value 
    return i.ToString() + i.ToString();  
} 

public static int i=0;//Here u declared and applied value, this is declared when your class get instanciated 

請查看評論

+0

**從審覈隊列**:我可以請求您請您在答案中添加更多的上下文。僅有代碼的答案很難理解。如果您可以在帖子中添加更多信息,它可以幫助提問者和未來的讀者。 – RBT