2012-03-18 99 views
2

這實際上是如何工作的?我認爲Main應該是「呼叫」。但是如果它被標記爲私人,那又怎麼可能呢?爲什麼允許私人入口?

public class Program 
{ 
    private static void Main() 
    { 
    } 
} 
+0

'private'方法不能被調用? – delnan 2012-03-18 18:16:56

+0

那麼,如果我的代碼解釋你的代碼,我是否必須遵循C#的規則?不,我可以做任何我想做的事。 – 2012-03-18 18:18:23

+0

@delnan然後你怎麼能調用私有方法? – Marlon 2012-03-18 18:18:25

回答

8

從喬恩斯基特上bytes.com:

基本上,主要方法的執行是通過特殊碼 在CLR中開始(或可能碼驅動該CLR開始與),其 不需要遵守相同的規則。

Source

此外,there's another question已經在這裏涵蓋了這個主題。

+0

謝謝。我在搜索時沒有看到那個話題。這解釋了它。 – Marlon 2012-03-18 18:20:36

3

按照與MSDN Main方法不應該是公共的:

主要類或結構內聲明的。主要是靜態的,並且不應該公開 。 (在前面的例子中,它接收到private的默認訪問。)封閉的類或結構不是 需要是靜態的。

+0

我沒有理由認爲它不是公開的,如果它是公開的,它允許其他程序調用它,這有時候會非常有用。這看起來像是從MSDN給我的一個壞建議:( – 2012-03-18 18:21:52

+0

這並不能解釋爲什麼,只是重複部分問題。 – ssube 2012-03-18 18:22:02

+0

@MarcinJuraszek,「必須」/「應該」/「不應該」可能根據http://www.faqs.org/rfcs/rfc2119.html使用:「不應該......意味着在特定情況下可能存在某些特定情況下有效的理由,當這種行爲是可以接受的或甚至是有用的......」。不是「推薦」,但可以,不像「不可以」 – 2012-03-18 18:39:21

0

當您執行代碼時,Main方法由CLR執行CLR編譯器搜索該Main方法。即使你用小寫字母給它,它也不會被調用。

0

.Net中的訪問修飾符是(非常強大的)建議。您可以調用任何方法或使用反射訪問任何屬性/字段。考慮這樣的代碼,其行爲有點像main調用時實際發生的情況。

public class EntryPointAttribute : System.Attribute 
{ 
    public string EntryPoint { get; private set; } 
    public EntryPointAttribute(string entryPoint) { this.EntryPoint = entryPoint; } 
} 

public static class EntryPointProcessor 
{ 
    public static void Process(object theObject) 
    { 
     Type t = theObject.GetType(); 
     var ep = t.GetCustomAttributes(typeof(EntryPointAttribute), true).FirstOrDefault(); 
     string entryPointName = ((EntryPointAttribute)ep).EntryPoint; 
     MethodInfo mi = t.GetMethod(entryPointName, BindingFlags.Static | BindingFlags.NonPublic); 
     mi.Invoke(null, new object[0] { }); 
    } 

} 

[EntryPoint("anentrypoint")] 
public class entryPointClass 
{ 
    private static void anentrypoint() 
    { 
     Console.WriteLine("in anentrypoint"); 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     EntryPointProcessor.Process(new entryPointClass()); 
    } 
} 
2

這是一種語言實現細節,CLR只是從程序集頭中讀取EntryPointToken值,並且不會對該標記的方法進行可訪問性檢查。底層調用是_AppDomain.ExecuteAssembly()。因此,我們需要轉向C#語言規範,第3.1節明確提到了輔助功能規則:

在C#中,每個方法都必須定義爲類或結構的成員。通常,方法的聲明可訪問性(第3.5.1節)由其聲明中指定的訪問修飾符(第10.3.5節)確定,類似地,聲明的類型的可訪問性由其聲明中指定的訪問修飾符確定。爲了給定類型的給定方法可被調用,類型和成員都必須是可訪問的。 但是,應用程序入口點是一種特殊情況。具體而言,執行環境可以訪問應用程序的入口點,而不管其聲明的可訪問性如何,並且不管其聲明的可訪問性如何,其封裝類型聲明

粗體部分記錄了CLR用於EntryPointToken的功能。 C#編譯器可能會驗證可訪問性,如果它想,但不。

+0

我不明白什麼是「無論其封閉類型聲明的聲明可訪問性」是什麼意思。「你會解釋說什麼意思嗎? – Destructor 2016-01-14 06:47:11