![](/img/trans.png)
[英]Why calling non-static method inside a static method in C# possible via class instance
[英]C# - Inside instance method, why can we access static members without using the class name?
這對我來說似乎違反直覺。 如果我們有一個具有靜態方法CountAllDogs()的Dog類,則C#禁止這樣調用它:myDog.CountAllDogs()。 (myDog是Dog類型的對象)。 但是,如果我們在實例方法Bark()中,則可以使用CountAllDogs()來簡單地調用它。 在實例方法Bark()中,上下文(“ this”)是對象myDog,而不是類本身,所以我想知道為什么允許這樣做嗎?
“為什么”的問題經常含糊不清,這一點也不例外。 除了回答您的含糊和令人困惑的問題外,我將回答另一個問題。
解決C#中不合格名稱的基本規則是什么?
解決不合格名稱的基本規則是從內到外搜索 。 假設您有:
using System;
namespace A {
namespace B {
using C;
class D
{
public static void E() {}
}
class F : D {
public static void G() {}
public void H()
{
Action i = ()=>{};
現在假設H
內的某個地方有一個不合格的名稱X
我們需要弄清楚這是什么意思。 因此,我們從內到外:
(這是一個草圖,其中省略了一些細節,例如如何處理別名等;如果需要這些細節,請閱讀規格。)
這里有趣的一點是, 基類被認為比詞法包含的program元素“更內部” 。 D的成員被認為是F的成員,因此在檢查B 之前必須先對其進行檢查。
這是基本原則。 為了方便起見,還添加了一些額外的規則。 例如,如果我們有X()
則在進行搜索時僅考慮可調用成員。 還有一條著名的“顏色顏色”規則,該規則表示,如果您有一個名為Color的類型和一個名為Color的Color類型的屬性,那么您還會調用它嗎? -那么Color的名稱查找規則很聰明,可以弄清楚您是指類型還是屬性,即使這意味着脫離了不合格名稱查找的基本規則。
現在您已經知道了基本規則,可以將其應用於您的情況。 為什么您可以不加資格地致電靜態會員? 因為不限定名稱查找的基本規則是“從內到外搜索”,所以查找具有該名稱的靜態元素 。 如果我們在H
並且有G()
則G
不是局部變量,但它是封閉類的可調用成員,因此它贏了。 如果我們在H
並且有E()
那么在H
或F
找不到它之后,就可以在D
中找到它。 等等。
當您調用不合格的實例成員時,同樣的事情。 解析了不合格的名稱, 如果結果是實例成員 ,則將this
用作該成員的接收者。
要調用實例成員,您當然需要一個實例。 如果you're媒體鏈接的情況下,構件內 ,當然你可以使用this
引用,它指向當前實例。 如果您從另一面從類外部調用實例成員,則應編寫如下內容:
myInstance.DoSomething();
因此, 實際上將this
用作限定符是多余的,如果您在方法內 ,則可以簡單地忽略它。
靜態成員doesn't知道任何情況,因此沒有this
。 再次添加類名是多余的信息,因為this
-keyowrd添加到實例成員。
編譯器應該足夠聰明,可以確定一個成員是否是靜態的,從而確定他是否需要一個實例。
我個人同意,添加可以在其中調用成員的上下文是一件好事,這在Java中甚至是強制執行的,例如,這避免了煩惱諸如m_
表示實例的前綴和s_
表示靜態成員的變量。 但是,編譯器已經知道了,這只是個問題。
所以說了這一點並沒有實際的必要,為什么應該或不應該這樣做,因為它不能避免任何錯誤,因此不會產生任何錯誤。 這只是一個約定,要更加嚴格。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.