2011-08-10 100 views
0

嘿,所有我在C#中新,我試圖調用的函數closeComm()像這樣:對象引用需要非靜態字段,方法或屬性

public void closeComm() 
    { 
     commIRToy.ClosePort(); 
     commProj.ClosePort(); 
     commTV.ClosePort(); 
     commAV.ClosePort(); 
    } 

    public static void loadAnotherRemote() 
    { 
     closeComm(); 
    } 

然而,這是給我的一個錯誤:的對象引用需要非靜態字段,方法或屬性

當我嘗試這樣說:

public static void closeComm() 
    { 
     commIRToy.ClosePort(); 
     commProj.ClosePort(); 
     commTV.ClosePort(); 
     commAV.ClosePort(); 
    } 

    public static void loadAnotherRemote() 
    { 
     closeComm(); 
    } 

我可以調用該函數,但所有commIRToy,commProj,co​​mmTV和commAV都有錯誤對象引用是非靜態字段,方法或屬性所必需的同樣的錯誤我得到了周圍的其他方式....

+1

您的loadAnotherRemote()方法是靜態的嗎? – BoltClock

+0

歡迎來到[SO]。很高興有你的問題,但請注意:1)沒有「C Sharp」這樣的東西。該語言是「C#」。 2)你不需要在標題中加入「C Sharp」這樣的東西 - 我們有標籤。 –

+0

關於術語的離題建議:在C#中,類型的可執行位稱爲**「methods」**,而不是「functions」。這兩個術語之間的一般概念是前者(方法)是一個類型的成員,而後者(函數)可以由他們自己存在,即。在一個類型之外。可能的例外情況:(1)「代表」。但是,即使這些不被稱爲「函數指針」,因爲它們是不同的東西。 (2)lambda表達式('(...)=> {...}')和匿名委託('delegate(...){...}');但即使這些通常被稱爲匿名方法,從來沒有「功能」。 – stakx

回答

3

你要麼需要讓你的commIRToycommProjcommTVcommAV田靜,或從loadAnotherRemote方法去除static關鍵字。

+0

Gotcha。謝謝devdigital! :O) – StealthRT

1

A 非靜態方法對類的特定實例進行操作。訪問成員變量時,它訪問它從中調用的實例的成員。 A 靜態方法不需要任何特定的實例被調用。由於它不通過實例調用,因此它不能引用任何特定於實例的變量,只能引用靜態變量。

在你的例子中,我假設(沒有看到所有的代碼),你可以使所有的方法和屬性靜態,使其工作。

這意味着,你應該在commIRToy等聲明前加字static

static PCComm.CommunicationManager commIRToy = new PCComm.CommunicationManager(); 

這將使它的工作 - 但我不會說這是從長遠來看,最好的設計。

1

您正在接收第一個錯誤,因爲loadAnotherRemote()是靜態的,但試圖調用非靜態方法。
您正在接收第二個錯誤,因爲在您調用靜態方法時,變量commIrTroy等等是類的實例,而不是靜態的。
雖然很難給出答案,因爲我不確定這些方法的背景。

0

A static方法在類的上下文中執行。您可以隨時致電classname.StaticMethod(),因爲編譯器可以毫不含糊地理解它。

當您省略static時,您可以定義一個在對象(類的實例)的上下文中執行的方法,通常使用new classname();創建。

您對closeComm()的調用無法編譯,因爲編譯器不知道執行該方法的對象是什麼。

您可以通過和實例方法調用static方法,但不能反其道而行,除非您有上下文對象。

如果您需要在特定對象的上下文中調用closeComm()(可能因爲您有很多實例),則loadAnotherRemote()方法需要對象引用。

0

C#規格:

10.6.2靜態和實例方法

當一個方法聲明包含static改性劑,該方法是 說是一個靜態方法。當不存在靜態修飾符時, 方法被稱爲實例方法。

靜態方法不能在特定實例上運行,並且它是編譯時錯誤,以在靜態方法中引用此錯誤。

MSDN:

靜態成員

靜態方法,字段,屬性或事件是一個類時,已創建任何類的實例,即使 調用。如果創建該類的任何實例爲 ,則不能用它們訪問靜態的 成員。只存在一個靜態字段和事件副本,並且靜態 方法和屬性只能訪問靜態字段和靜態 事件。靜態成員通常用於表示不響應對象狀態而改變的數據或計算結果;對於 實例,數學庫可能包含計算 正弦和餘弦的靜態方法。

在我看來,你似乎試圖用靜態方法管理實例。如果是這樣,請考慮使用單例模式,如果您只需要一次管理一個實例或使用靜態方法管理靜態實例列表。如果不是,那麼這種方法就不會是靜態的,因此除非它不僅僅是closeComm();,否則將是無用的。

真誠,馬克西姆

1

簡短的回答:

試試這個:

public static void loadAnotherRemote() 
{ 
    new TypeThatContainsCloseComm(…).closeComm(); 
} 

較長的答案:

首先,你需要了解static:不管被宣佈爲static不屬於到任何特定的實例的類型,但屬於類型本身。也就是說,如果你有一個靜態方法TypeThatContainsCloseComm.closeComm,那麼你就可以把它叫做:

TypeThatContainsCloseComm.closeComm(…) 
// ^^^^^^^^^^^^^^^^^^^^^^^^^^ 
//  name of the type! 

但是,未申報static只能在特定實例被調用,因爲這是所有方法,他們屬於什麼於:

var commProj = new TypeThatContainsClosePort(); // <- create a instance here 
    commProj.ClosePort(); 
// ^^^^^^^^ 
// instance of a type! 

現在,回到你原來的代碼:

public void closeComm() 
{ 
    commIRToy.ClosePort(); 
    commProj.ClosePort(); 
    commTV.ClosePort(); 
    commAV.ClosePort(); 
} 

public static void loadAnotherRemote() 
{ 
    // this method is static, therefore we are not "within" an object instance 
    closeComm(); // ERROR: closeComm is not static, therefore you need 
        // some object instance to call it! 
} 

&hellip;並返回到第二次嘗試:

public static void closeComm() 
{ 
    commIRToy.ClosePort(); // ERROR if commIRToy, commProj, commTV, commAV 
    commProj.ClosePort(); //  are not declared static, because we're 
    commTV.ClosePort();  //  in a static method and thus "outside" an 
    commAV.ClosePort();  //  object instance, yet these fields are 
}       //  declared within one. 

public static void loadAnotherRemote() 
{ 
    closeComm(); // this call is fine now, since `closeComm` is static, 
        // no object instance is required to call it. 
} 
相關問題