2010-02-17 92 views
13

我在一個類中有一個靜態函數。爲什麼我只能從靜態函數中訪問靜態成員?

每當我嘗試使用非靜態數據成員,我得到以下編譯錯誤。

一個對象引用是所必需的非靜態字段,方法或屬性構件

爲什麼表現得像是什麼?

+0

幾乎重複:http://stackoverflow.com/questions/290884/what-is-the-reason-behind-non-static-method-cannot-be-referenced-from-a-static-c – 2010-02-17 18:27:53

+0

@ casperOne:請張貼重複的建議作爲意見,而不是重寫問題。有一個原因需要5票近距離投票。 – danben 2010-02-17 18:28:26

+2

標題有點誤導......您可以從非靜態函數中訪問靜態成員。 – froadie 2010-02-17 18:29:12

回答

19

非靜態成員屬於一個實例。沒有某種方式解決你正在談論的課程的實例是沒有意義的。在一個靜態的上下文中,你沒有一個實例,這就是爲什麼你沒有明確提到一個對象引用就不能訪問一個非靜態成員。

事實上,你可以通過顯式指定對象引用訪問非靜態成員在靜態方面:

class HelloWorld { 
    int i; 
    public HelloWorld(int i) { this.i = i; } 
    public static void Print(HelloWorld instance) { 
     Console.WriteLine(instance.i); 
    } 
} 

var test = new HelloWorld(1); 
var test2 = new HelloWorld(2); 
HelloWorld.Print(test); 

沒有明確提到的實例在Print方法,它怎麼會知道它應該打印1而不是2?

+0

好的,當然 - 一個靜態方法可以訪問作爲參數傳入的實例上的東西....好點,但我猜不是OP真正在說什麼...... – 2010-02-17 18:24:05

+3

@marc_s:我知道OP是什麼想知道。我認爲這種回答方式可以更有效地闡明原因。它證明它不是對靜態方法施加任何限制,而是它可以解決的唯一方法。 – 2010-02-17 18:25:56

+0

+1,它是一個常見的場景,例如DependencyPropertyChanged回調。 – AnthonyWJones 2010-02-17 18:38:05

2

靜態方法不能直接訪問類的任何非靜態成員變量。

畢竟:一個靜態方法可以被稱爲沒有類的實例,即使存在。你如何訪問一個不存在的實例上的成員變量?

(當然,作爲邁赫達德指出:你可以在你的類的實例傳遞給靜態方法和訪問該實例的一切 - 但是這不是你在說什麼,對吧?)

5

實例方法依賴於特定實例的狀態才能運行。

比方說,你有這個類,它具有你所描述的情景:

class Person 
{ 
    static PrintName() 
    { 
     // Not legal, but let's say it is for now. 
     Console.WriteLine(Name); 
    } 

    private Name { get; set; } 
} 

希望,現在的問題是顯而易見的。因爲Name是實例成員,所以您需要該類的實際實例,因爲Name可以在不同實例之間有所不同。

因此,未附加到實例的靜態方法不知道要使用哪個實例。你必須明確指出哪一個。

2

靜態函數只能使用靜態成員,並調用靜態函數。

如所提到的,一個靜態函數可以在操作一個類的實例,但不能從一個類的實例(由於缺乏更具描述性的詞)。例如:

class MyClass 
{ 
    public int x; 
    public static int y; 

    public static void TestFunc() 
    { 
     x = 5; // Invalid, because there is no 'this' context here 
     y = 5; // Valid, because y is not associated with an object instance 
    } 

    public static void TestFunc2(MyClass instance) 
    { 
     instance.x = 5; // Valid 
     instance.y = 5; // Invalid in C# (valid w/ a warning in VB.NET) 
    } 
}
1

您無法從靜態函數中訪問非靜態數據。這是因爲可以調用靜態函數,而不管該類是否有任何實例化對象。但是,非靜態數據依賴於類的特定對象(實例化)。由於您不能確定在調用靜態函數時實例化了任何對象,因此從其訪問非靜態數據是不合邏輯的(因此也是不允許的)。

這個問題已經被問了幾次SO上以不同的形式/針對不同的語言:

+1

您的第一個鏈接不正確 - 它指向Java問題 – ChrisF 2010-02-17 18:26:45

+0

@ChrisF - 謝謝。糾正。 – froadie 2010-02-17 18:28:27

1

「非靜態數據成員」的定義是「實例數據成員」。換句話說,非靜態成員屬於您創建的類的實例。

靜態方法不會在類的任何特定實例的上下文中運行。因此,當你要求這樣的方法使用非靜態成員時,它不知道應該嘗試從哪個類的0個或多個實例中獲取數據。

+0

+1「,它不知道應該嘗試從哪個類的0個或更多實例中獲取數據。 – 2013-11-29 05:11:35