为什么允许入口点是私有的?

时间:2012-03-18 18:15:14

标签: c# .net

这实际上如何运作?我以为Main应该被称为“被叫”。但如果标记为私有,那怎么可能呢?

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

5 个答案:

答案 0 :(得分:8)

来自bytes.com上的Jon Skeet:

  

基本上,main方法的执行是由特殊代码启动的   在CLR内(或可能是驱动CLR开始的代码)   不需要遵守相同的规则。

Source

此外,there's another question已涵盖此主题。

答案 1 :(得分:3)

MSDN之后,Main方法不应公开:

  

Main在类或结构中声明。主要必须是静态的   不应公开。 (在前面的示例中,它接收private的默认访问权限。)封闭的类或结构不是   必须是静态的。

答案 2 :(得分:2)

这是一个语言实现细节,CLR只是从程序集头读取EntryPointToken值,并且不对该方法的方法执行可访问性检查。底层调用是_AppDomain.ExecuteAssembly()。因此,我们需要转向C#语言规范,第3.1节明确提到可访问性规则:

  

在C#中,每个方法都必须定义为类或结构的成员。通常,方法的声明可访问性(第3.5.1节)由其声明中指定的访问修饰符(第10.3.5节)确定,类似地,声明的类型的可访问性由其声明中指定的访问修饰符确定。为了使给定类型的给定方法可以调用,类型和成员都必须是可访问的。 但是,应用程序入口点是一种特殊情况。具体而言,执行环境可以访问应用程序的入口点,无论其声明的可访问性如何,并且无论其封闭类型声明的声明可访问性如何

粗体部分记录了CLR对EntryPointToken的作用。如果C#编译器可以验证可访问性,但是没有。

答案 3 :(得分:0)

当您执行代码时,CLR将执行Main方法CLR编译器搜索该Main方法。即使你用小写字母给主要字母,它也不会被调用。

答案 4 :(得分:0)

.Net中的Acces修饰符是(非常强大)的建议。您可以使用反射调用任何方法或访问任何属性/字段。考虑这样的代码,其行为与调用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());
    }
}