Как это работает? Я думал, что Main
должен был «называться». Но как это возможно, если оно выделено частным?Почему точка входа разрешена как конфиденциальная?
public class Program
{
private static void Main()
{
}
}
Как это работает? Я думал, что Main
должен был «называться». Но как это возможно, если оно выделено частным?Почему точка входа разрешена как конфиденциальная?
public class Program
{
private static void Main()
{
}
}
От Jon тарелочкам на bytes.com:
В основном, выполнение основного метода запускается специальным кодом в CLR (или, возможно, код вождения CLR, чтобы начать с), который не должен соблюдать те же правила.
Кроме того, there's another question, которая охватывает эту тему уже здесь.
Спасибо. Я не видел эту тему, когда искал. Что объясняет его. – Marlon
Следуя MSDN Главный метод не должен быть публичным:
Main объявляется внутри класса или структуры. Основной должен быть статический, и не должно быть общедоступным. (В более раннем примере он получает доступ по умолчанию для частного.) Класс или структура окружения не является , который должен быть статическим.
Я не вижу причин для этого * не * быть открытым - и если он * является общедоступным, что позволяет другим программам называть его, что иногда может быть очень полезно. Это выглядит как плохой совет от MSDN для меня :( –
Это не объясняет, почему вообще, просто повторяет часть вопроса. – ssube
@MarcinJuraszek, «must»/«should»/«should not» скорее всего используется в соответствии с http://www.faqs.org/rfcs/rfc2119.html: «НЕ ДОЛЖНО ... означает, что в конкретных обстоятельствах могут существовать обоснованные причины, когда конкретное поведение приемлемо или даже полезно ...». не рекомендуется, но нормально, в отличие от «must not». –
Основной метод выполняется CLR, когда вы выполняете свой код. CLR-компилятор ищет этот Основной метод. Даже если вы даете основное письмо небольшими буквами, он не будет вызван.
Модификаторы 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());
}
}
Это деталь реализации языка, CLR просто считывает значение EntryPointToken из заголовка сборки и не выполняет никаких специальных возможностей проверки на методе с этим маркером. Основной вызов - _AppDomain.ExecuteAssembly(). Поэтому нам нужно обратиться к Спецификации языка C#, в разделе 3.1 явно указано правило доступности:
В C# каждый метод должен быть определен как член класса или структуры. Обычно объявленная доступность (§3.5.1) метода определяется модификаторами доступа (§10.3.5), указанными в его объявлении, и аналогично объявленная доступность типа определяется модификаторами доступа, указанными в его объявлении. Для того, чтобы данный метод данного типа был доступен для вызова, должны быть доступны как тип, так и член. Однако точка входа приложения является частным случаем. В частности, среда выполнения может получить доступ к точке входа приложения независимо от ее объявленной доступности и независимо от объявленной доступности ее объявлений типа вложения.
Полужирный раздел документирует то, что делает CLR с EntryPointToken. Компилятор C# мог бы проверить доступность, если захочет, но это не так.
Я не понимал, что значит «независимо от заявленной доступности его объявлений вложенных типов». Будет ли говорить, что это значит сказать? – Destructor
'private' методы не могут быть вызваны? – delnan
Ну, если мой код интерпретирует ваш код, должен ли я следовать правилам C#? Нет, я могу делать все, что захочу. –
@delnan Как вы можете назвать частный метод? – Marlon