2012-03-18 2 views
2

Как это работает? Я думал, что Main должен был «называться». Но как это возможно, если оно выделено частным?Почему точка входа разрешена как конфиденциальная?

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

'private' методы не могут быть вызваны? – delnan

+0

Ну, если мой код интерпретирует ваш код, должен ли я следовать правилам C#? Нет, я могу делать все, что захочу. –

+0

@delnan Как вы можете назвать частный метод? – Marlon

ответ

8

От Jon тарелочкам на bytes.com:

В основном, выполнение основного метода запускается специальным кодом в CLR (или, возможно, код вождения CLR, чтобы начать с), который не должен соблюдать те же правила.

Source

Кроме того, there's another question, которая охватывает эту тему уже здесь.

+0

Спасибо. Я не видел эту тему, когда искал. Что объясняет его. – Marlon

3

Следуя MSDN Главный метод не должен быть публичным:

Main объявляется внутри класса или структуры. Основной должен быть статический, и не должно быть общедоступным. (В более раннем примере он получает доступ по умолчанию для частного.) Класс или структура окружения не является , который должен быть статическим.

+0

Я не вижу причин для этого * не * быть открытым - и если он * является общедоступным, что позволяет другим программам называть его, что иногда может быть очень полезно. Это выглядит как плохой совет от MSDN для меня :( –

+0

Это не объясняет, почему вообще, просто повторяет часть вопроса. – ssube

+0

@MarcinJuraszek, «must»/«should»/«should not» скорее всего используется в соответствии с http://www.faqs.org/rfcs/rfc2119.html: «НЕ ДОЛЖНО ... означает, что в конкретных обстоятельствах могут существовать обоснованные причины, когда конкретное поведение приемлемо или даже полезно ...». не рекомендуется, но нормально, в отличие от «must not». –

0

Основной метод выполняется CLR, когда вы выполняете свой код. CLR-компилятор ищет этот Основной метод. Даже если вы даете основное письмо небольшими буквами, он не будет вызван.

0

Модификаторы Acces в .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

Смежные вопросы