2012-03-18 147 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