这实际上如何运作?我以为Main
应该被称为“被叫”。但如果标记为私有,那怎么可能呢?
public class Program
{
private static void Main()
{
}
}
答案 0 :(得分:8)
来自bytes.com上的Jon Skeet:
基本上,main方法的执行是由特殊代码启动的 在CLR内(或可能是驱动CLR开始的代码) 不需要遵守相同的规则。
此外,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());
}
}