2

How does this actually work? I thought Main was supposed to be "called". But how is that possible if it's marked private?

public class Program
{
    private static void Main()
    {
    }
}
Marlon
  • 19,924
  • 12
  • 70
  • 101
  • `private` methods can't be called? –  Mar 18 '12 at 18:16
  • Well, if my code is interpreting your code, do I have to follow C#'s rules? No, I can do whatever I want. – Ed S. Mar 18 '12 at 18:18
  • @delnan How can you call the private method then? – Marlon Mar 18 '12 at 18:18
  • 1
    @Marlon I just call it. Sure, most code outside the class can't call it easily (though there's still reflection), but *of course* private methods can be called. They'd be useless otherwise. –  Mar 18 '12 at 18:19
  • 1
    @delnan Isn't that the whole point of my question? If the method is private that means it can only be called within my class. How does this method get called then is my question. – Marlon Mar 18 '12 at 18:21

5 Answers5

8

From Jon Skeet on bytes.com:

Basically, the execution of the main method is started by special code within the CLR (or possibly code driving the CLR to start with) which doesn't need to obey the same rules.

Source

Also, there's another question that covers this topic here already.

Community
  • 1
  • 1
Cᴏʀʏ
  • 105,112
  • 20
  • 162
  • 194
3

Following to MSDN the Main method should not be public:

Main is declared inside a class or struct. Main must be static and it should not be public. (In the earlier example, it receives the default access of private.) The enclosing class or struct is not required to be static.

MarcinJuraszek
  • 124,003
  • 15
  • 196
  • 263
  • I see no reason for it to *not* be public - and if it *is* public, that allows other programs to call it, which can be very useful sometimes. This looks like a bad bit of advice from MSDN to me :( – Jon Skeet Mar 18 '12 at 18:21
  • This doesn't explain the why at all, just repeats part of the question. – ssube Mar 18 '12 at 18:22
  • @MarcinJuraszek, "must"/"should"/"should not" are likely used according to http://www.faqs.org/rfcs/rfc2119.html : "SHOULD NOT ...mean that there may exist valid reasons in particular circumstances when the particular behavior is acceptable or even useful...". Eseentially not recomended, but ok, unlike "must not". – Alexei Levenkov Mar 18 '12 at 18:39
2

It is a language implementation detail, the CLR simply reads the EntryPointToken value from the assembly header and performs no accessibility checks on the method with that token. The underlying call is _AppDomain.ExecuteAssembly(). So we'll need to turn to the C# Language Specification, section 3.1 mentions the accessibility rule explicitly:

In C#, every method must be defined as a member of a class or struct. Ordinarily, the declared accessibility (§3.5.1) of a method is determined by the access modifiers (§10.3.5) specified in its declaration, and similarly the declared accessibility of a type is determined by the access modifiers specified in its declaration. In order for a given method of a given type to be callable, both the type and the member must be accessible. However, the application entry point is a special case. Specifically, the execution environment can access the application's entry point regardless of its declared accessibility and regardless of the declared accessibility of its enclosing type declarations.

The bolded section documents what the CLR does with the EntryPointToken. The C# compiler could verify accessibility if it wanted to, but doesn't.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • I didn't understand what is meaning of "regardless of the declared accessibility of its enclosing type declarations." Will u plz explain what does it mean to say? – Destructor Jan 14 '16 at 06:47
0

the Main method is executed by CLR when ever you execute your code CLR compiler searches for that Main method. Even if you give main in small letters it wont get called.

Kishore Kumar
  • 12,675
  • 27
  • 97
  • 154
0

Acces modifiers in .Net are (really strong) suggestions. You can call any method or access any property/field using reflection. Consider code like this which behaves somewhat like what is actually going on when main gets called.

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());
    }
}
Yaur
  • 7,333
  • 1
  • 25
  • 36